home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cnstrnts / thinglab.lha / ThingLabII / SIGGRAPH-Demo.st < prev    next >
Text File  |  1993-08-09  |  103KB  |  3,423 lines

  1. 'From Smalltalk-80, Version 2.3 of 13 June 1988 on 4 September 1991 at 8:32:24 am'!
  2.  
  3.  
  4.  
  5. !Plan methodsFor: 'interpretation'!
  6.  
  7. execute
  8.     "Execute my constraints in order."
  9.  
  10.     Sensor leftShiftDown ifTrue: [Transcript show: '*** executing plan ***'; cr].
  11.     historyVariables do: [:v | v advanceHistory].
  12.     constraints do: 
  13.         [:c | 
  14.         c execute.
  15.         Sensor leftShiftDown ifTrue: [Transcript show: c printString; cr]]! !
  16.  
  17.  
  18. !Planner class methodsFor: 'planning/value propagation'!
  19.  
  20. makePlan: seedConstraints
  21.     "Extract a plan for resatisfaction starting from the given seed constraints, usually a set of input constraints. This method assumes that stay optimization is desired; the plan will contain only constraints whose output variables are not stay. Constraints that do no computation, such as stay and edit constraints, are not included in the plan."
  22.     "Details: The outputs of a constraint are marked when it is added to the plan under construction. A constraint may be appended to the plan when all its input variables are known. A variable is known if either a) the variable is marked (indicating that has been computed by a constraint appearing earlier in the plan), b) the variable is 'stay' (i.e. it is a constant at plan execution time), or c) the variable is not determined by any constraint. The last provision is for past states of history variables, which are not stay but which are also not computed by any constraint."
  23.     "Assume: seedConstraints are all satisfied."
  24.  
  25.     | todo mark plan hotC out inC |
  26.     todo _ seedConstraints.
  27.     mark _ self newMark.
  28.     plan _ Plan new.
  29.     (todo isEmpty) ifFalse: [hotC _ todo removeFirst].
  30.     [hotC == nil] whileFalse:
  31.         [((hotC output mark ~= mark) and:        "not in plan already and..."
  32.           [hotC inputsKnown: mark])            "eligible for inclusion"
  33.             ifTrue:
  34.                 [
  35. hotC output stay ifFalse: [
  36.                 plan append: hotC.
  37. ].
  38.                  out _ hotC output.
  39.                  out mark: mark.
  40.                  hotC _ self nextConstraintIn: todo downstreamOf: out]
  41.             ifFalse:
  42.                 [(hotC output mark ~= mark) ifTrue:
  43.                     ["this code backs up in the constraint graph; this is useful when not all the source nodes are easily determined"
  44.                      hotC inputsDo:
  45.                         [: inVar |
  46.                          inC _ inVar determinedBy.
  47.                          ((inVar stay) or:
  48.                           [(inC == nil) or:
  49.                           [inVar mark == mark]]) ifFalse:
  50.                             [todo addFirst: inC]]].
  51.                  hotC _ (todo isEmpty)
  52.                     ifTrue: [nil]
  53.                     ifFalse: [todo removeFirst]]].
  54.     ^plan finalize! !
  55.  
  56. InvisiblePointGlyph subclass: #MacDrawDraggerGlyph
  57.     instanceVariableNames: 'exists myDash myFlexiConstraint theScene editConstraints plan '
  58.     classVariableNames: 'CopyConstraint '
  59.     poolDictionaries: ''
  60.     category: 'Minstrel-SIGGRAPH'!
  61.  
  62.  
  63. !MacDrawDraggerGlyph methodsFor: 'initialize-release'!
  64.  
  65. initialize
  66.     self initialize: '?'!
  67.  
  68. initialize: i
  69.     super initialize.
  70.     exists _ FreeVariable value: true.! !
  71.  
  72. !MacDrawDraggerGlyph methodsFor: 'accessing'!
  73.  
  74. dash
  75.     ^myDash!
  76.  
  77. dash: d scene: s 
  78.     myDash _ d.
  79.     theScene _ s!
  80.  
  81. exists
  82.     ^exists!
  83.  
  84. height
  85.     ^y!
  86.  
  87. isSpare
  88.     ^exists value and: [myDash exists value not]!
  89.  
  90. offset
  91.     ^x! !
  92.  
  93. !MacDrawDraggerGlyph methodsFor: 'glyph protocol'!
  94.  
  95. displayOn: aDisplayMedium at: aDisplayPoint clip: clipBox 
  96.     | p box |
  97.     exists value
  98.         ifTrue: 
  99.             [self
  100.                 vLineFrom: x value @ MacDrawDemo dragTop
  101.                 length: MacDrawDemo dragBottom - MacDrawDemo dragTop
  102.                 on: aDisplayMedium
  103.                 at: aDisplayPoint
  104.                 clip: clipBox.
  105.             "box _ MacDrawDemo dragBox.  
  106.             p _ self asPoint - (box width // 2 @ (box height // 2)) + 
  107.             aDisplayPoint.  
  108.             box moveTo: p.  
  109.             aDisplayMedium fill: box mask: Form white.  
  110.             aDisplayMedium border: box width: 1"
  111.             MacDrawDemo draggerBoxForm displayOn: aDisplayMedium at: aDisplayPoint + self asPoint]!
  112.  
  113. isSelectable
  114.     ^exists value!
  115.  
  116. isVisible
  117.     ^true!
  118.  
  119. locationPoints
  120.     ^Array with: self! !
  121.  
  122. !MacDrawDraggerGlyph methodsFor: 'printing'!
  123.  
  124. printOn: aStream 
  125.     | title |
  126.     title _ self class name.
  127.     aStream nextPutAll: ((title at: 1) isVowel
  128.                             ifTrue: ['an ']
  129.                             ifFalse: ['a '])
  130.                         , title! !
  131.  
  132. !MacDrawDraggerGlyph methodsFor: 'mouse'!
  133.  
  134. handleMouseDown: mousePoint view: view 
  135.     Cursor execute
  136.         showWhile: 
  137.             [editConstraints _ theScene editConstraintsFor: self and: myDash.
  138.             plan _ Planner extractPlanFromInputConstraints: editConstraints.
  139.             view computeBackground]!
  140.  
  141. handleMouseMove: mousePoint view: view
  142. "MessageTally spyOn: [
  143. 1 to: 10 do: [:i |"
  144.     plan execute.
  145.     view displayFeedback
  146. "]]"!
  147.  
  148. handleMouseUp: mousePoint view: view 
  149.     Cursor execute
  150.         showWhile: 
  151.             [editConstraints do: [:each | each destroyConstraint].
  152.             editConstraints _ nil.
  153.             plan release.
  154.             plan _ nil.
  155.             theScene cleanUpFor: self and: myDash.
  156.             view displayScene]!
  157.  
  158. wantsMouse
  159.     ^true! !
  160.  
  161. !MacDrawDraggerGlyph methodsFor: 'scene access'!
  162.  
  163. doDashDraggerAlignDefault: idx 
  164.     "The default alignment is to keep them aligned.  However, if the dash 
  165.     does not exist, then don't bother."
  166.  
  167.     myFlexiConstraint notNil
  168.         ifTrue: 
  169.             [myFlexiConstraint destroyConstraint.
  170.             myFlexiConstraint _ nil].
  171.     myDash exists value ifTrue: [myFlexiConstraint _ (FlexiEqualityConstraint
  172.                     var: myDash right0
  173.                     var: self offset
  174.                     strength: #default)
  175.                     name: idx printString , ':dash right0 = drag offset']!
  176.  
  177. doDashDraggerAlignMovement: idx 
  178.     "When moving the last dragger, we use a different constraint."
  179.  
  180.     myFlexiConstraint notNil
  181.         ifTrue: 
  182.             [myFlexiConstraint destroyConstraint.
  183.             myFlexiConstraint _ nil].
  184.     CopyConstraint isNil ifTrue: [CopyConstraint _
  185.             Constraint names: #(a b) methods: #('a _ b')].
  186.     myFlexiConstraint _ ("FlexiEqualityConstraint"
  187.                         CopyConstraint copy
  188.                 var: self offset
  189.                 var: myDash right1
  190.                 strength: #required)
  191.                 name: idx printString , ':dragger = right1'! !
  192. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  193.  
  194. MacDrawDraggerGlyph class
  195.     instanceVariableNames: ''!
  196.  
  197.  
  198. !MacDrawDraggerGlyph class methodsFor: 'classification'!
  199.  
  200. glyphCategory
  201.     ^'SIGGRAPH'! !
  202.  
  203. !MacDrawDraggerGlyph class methodsFor: 'constraint release'!
  204.  
  205. releaseConstraints
  206.     "MacDrawDraggerGlyph releaseConstraints"
  207.  
  208.     CopyConstraint _ nil! !
  209.  
  210. PointGlyph subclass: #PlanetGlyph
  211.     instanceVariableNames: 'form '
  212.     classVariableNames: 'DefaultForms '
  213.     poolDictionaries: ''
  214.     category: 'Minstrel-SIGGRAPH'!
  215.  
  216.  
  217. !PlanetGlyph methodsFor: 'initialize-release'!
  218.  
  219. initialize
  220.     super initialize.
  221.     form _ Form dotOfSize: 5! !
  222.  
  223. !PlanetGlyph methodsFor: 'accessing'!
  224.  
  225. form1
  226.     self form: (DefaultForms at: 1)!
  227.  
  228. form2
  229.     self form: (DefaultForms at: 2)!
  230.  
  231. form2b
  232.     self form: (DefaultForms at: 4)!
  233.  
  234. form3
  235.     self form: (DefaultForms at: 3)!
  236.  
  237. form: f 
  238.     form _ f.
  239.     form offset: (form width // 2) negated @ (form height // 2) negated! !
  240.  
  241. !PlanetGlyph methodsFor: 'glyph protocol'!
  242.  
  243. boundingBox
  244.     | offset |
  245.     offset _ form boundingBox extent // 2.
  246.     offset _ offset x negated @ offset y negated.
  247.     ^(form boundingBox copy translateBy: self asPoint)
  248.         translateBy: offset!
  249.  
  250. containsPoint: aPoint 
  251.     ^self boundingBox containsPoint: aPoint!
  252.  
  253. displayOn: aDisplayMedium at: aDisplayPoint clip: clipBox 
  254.     form
  255.         displayOn: aDisplayMedium
  256.         at: aDisplayPoint x + x value rounded @ (aDisplayPoint y + y value rounded)
  257.         clippingBox: clipBox! !
  258.  
  259. !PlanetGlyph methodsFor: 'enumeration'!
  260.  
  261. selectableGlyphsDo: aBlock 
  262.     aBlock value: self.!
  263.  
  264. visibleGlyphsDo: aBlock 
  265.     aBlock value: self.! !
  266. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  267.  
  268. PlanetGlyph class
  269.     instanceVariableNames: ''!
  270.  
  271.  
  272. !PlanetGlyph class methodsFor: 'class initialization'!
  273.  
  274. initialize
  275.     "PlanetGlyph initialize."
  276.  
  277.     DefaultForms _ Array new: 4.
  278.     DefaultForms at: 1 put: (Form
  279.             extent: 40 @ 40
  280.             fromArray: #(0 12288 0 1 56704 0 23 30576 0 93 56796 0 119 30582 0 477 56797 0 887 30583 0 1501 56797 49152 1911 30583 24576 3549 56797 49152 6007 30583 28672 7645 56797 53248 14199 30583 28672 7645 56797 55296 30583 30583 29696 24029 56797 56320 30583 30583 29696 24029 56797 56320 30583 30583 29696 56797 56797 56320 30583 30583 30208 24029 56797 56320 30583 30583 29696 24029 56797 56320 30583 30583 29696 7645 56797 55296 14199 30583 28672 7645 56797 55296 6007 30583 28672 7645 56797 53248 1911 30583 24576 1501 56797 49152 887 30583 0 477 56797 0 119 30582 0 29 56792 0 7 30560 0 1 56704 0 0 4096 0 0 0 0 )
  281.             offset: 0 @ 0).
  282.     DefaultForms at: 2 put: (Form
  283.             extent: 30 @ 30
  284.             fromArray: #(2 0 21 16384 170 43008 341 21504 682 43520 1365 21760 2730 43648 5461 21824 10922 43680 5461 21824 10922 43680 21845 21840 10922 43680 21845 21840 43690 43688 21845 21840 10922 43680 21845 21840 10922 43680 5461 21824 10922 43680 5461 21824 2730 43648 1365 21760 682 43520 341 21504 170 43008 21 16384 2 0 0 0 )
  285.             offset: 0 @ 0).
  286.     DefaultForms at: 3 put: (Form
  287.             extent: 20 @ 20
  288.             fromArray: #(64 0 544 0 2184 0 546 0 2184 32768 8738 0 2184 32768 8738 0 2184 32768 8738 8192 2184 32768 8738 0 2184 32768 8738 0 2184 32768 546 0 2184 0 544 0 0 0 0 0 )
  289.             offset: 0 @ 0).
  290.     DefaultForms at: 4 put: (Form
  291.             extent: 30 @ 30
  292.             fromArray: #(2 0 29 49152 375 29696 477 56320 887 30208 3549 56704 6007 30528 7645 56768 14199 30560 7645 56768 14199 30560 24029 56784 30583 30576 24029 56784 30583 30576 24029 56784 30583 30576 24029 56784 30583 30576 7645 56768 14199 30560 7645 56768 6007 30528 1501 56576 1911 30464 477 56320 375 28672 29 49152 2 0 0 0 )
  293.             offset: 0 @ 0)! !
  294.  
  295. !PlanetGlyph class methodsFor: 'classification'!
  296.  
  297. glyphCategory
  298.     ^'SIGGRAPH'! !
  299.  
  300. PlanetGlyph initialize!
  301.  
  302.  
  303. EqualityConstraint subclass: #FlexiEqualityConstraint
  304.     instanceVariableNames: ''
  305.     classVariableNames: ''
  306.     poolDictionaries: ''
  307.     category: 'Minstrel-SIGGRAPH'!
  308.  
  309.  
  310. !Scene reorganize!
  311. ('initialize-release' initialize)
  312. ('accessing' constraintCount viewHeightVar viewWidthVar)
  313. ('testing' isAnimated)
  314. ('glyphs access' glyphsVar inputGlyphsDo: selectableGlyphsDo: topLevelGlyphs topLevelGlyphsDo: visibleGlyphsDo:)
  315. ('glyphs' addGlyph: moveToFront: moveToRear: removeGlyph:)
  316. ('selections' clearSelection deselect: select: selected toggleSelect:)
  317. ('background processing' backgroundTask: computeBackgroundPlan initialAnimationConstraints)
  318. !
  319.  
  320.  
  321.  
  322. !Scene methodsFor: 'testing'!
  323.  
  324. isAnimated
  325.     "This message should really be implemented with some other mechanism such as 
  326.     looking at all the constraints and return true if any span time boundries."
  327.  
  328.     ^false! !
  329.  
  330. !Scene methodsFor: 'background processing'!
  331.  
  332. backgroundTask: theView 
  333.     "The controller sends this message to the model when nothing else is happening. 
  334.     This allows the model to do background processing to support, for example, a 
  335.     simulation or an animation."
  336.  
  337.     ^self!
  338.  
  339. computeBackgroundPlan
  340.     "The controller sends this message to the model when it wants to create a plan 
  341.     to animate things when nothing else is going on."
  342.  
  343.     ^nil!
  344.  
  345. initialAnimationConstraints
  346.     "The controller sends this message to the model when it wants to create a plan 
  347.     to animate things when something is going on."
  348.  
  349.     ^#()! !
  350.  
  351. Object subclass: #DemoComments
  352.     instanceVariableNames: ''
  353.     classVariableNames: ''
  354.     poolDictionaries: ''
  355.     category: 'Minstrel-SIGGRAPH'!
  356.  
  357. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  358.  
  359. DemoComments class
  360.     instanceVariableNames: ''!
  361.  
  362.  
  363. !DemoComments class methodsFor: 'instance creation'!
  364.  
  365. from: aClass 
  366.     | topView holder view |
  367.     topView _ SpecialSystemView
  368.                 model: nil
  369.                 label: 'Demonstration Information'
  370.                 minimumSize: aClass infoSize.
  371.     holder _ StringHolder new initialize.
  372.     holder contents: aClass comment.
  373.     view _ StringHolderView container: holder.
  374.     topView borderWidth: 1; addSubView: view.
  375.     topView controller open! !
  376.  
  377.  
  378. !BasicRectangleGlyph methodsFor: 'accessing'!
  379.  
  380. asRectangle
  381.     ^left value @ top value corner: right value @ bottom value!
  382.  
  383. bottomLeft
  384.     ^left value @ bottom value!
  385.  
  386. bottomRight
  387.     ^right value @ bottom value!
  388.  
  389. center
  390.     ^center!
  391.  
  392. corner
  393.     ^self bottomRight!
  394.  
  395. extent
  396.     ^self width @ self height!
  397.  
  398. origin
  399.     ^self topLeft!
  400.  
  401. topLeft
  402.     ^left value @ top value!
  403.  
  404. topRight
  405.     ^right value @ top value! !
  406.  
  407. Scene subclass: #CFKDemo
  408.     instanceVariableNames: ''
  409.     classVariableNames: ''
  410.     poolDictionaries: ''
  411.     category: 'Minstrel-SIGGRAPH'!
  412. CFKDemo comment:
  413. '                        ***** Introducing Constraints (Celsius-Fahrenheit-Kelvin) *****
  414.  
  415. Just as a database demo is not complete with the Employee relation and a graphics demo is not complete without rendering a teapot, a constraint demo is not complete with the Celsius-Fahrenheit example.
  416.  
  417. Constraints are multi-directional, automatically-maintained assertions about the state of a system.  For example, the relation between Celsius and Fahrenheit temperatures is a constraint.  Constraints are often stated as equations, but other mechanism are both possible and are used in these demos.
  418.  
  419. This demo uses many different types of constraints: arithmetic constraints to maintain the relation between the different interpretations of temperature; layout constraints to keep the title under each thermometer, the equations between the thermometers, and the number beside the mercury; and consistency constraints to keep the mercury height proportional to the temperature which in turn is equal to the text printed beside it.  Last, but not least, special graphical constraints are used to control the display when the temperature gets too cold or too hot (Try 10 Kelvin or 200 Celsius!!).  Yes, the entire demo is composed of many smaller objects working together, synchronized and kept consistent with constraints.
  420.  
  421. Interesting actions to try are: (1) moving the mercury up and down, (2) selecting and then entering a temperature directly (use <delete> and the number keys), (3) switching to "edit" mode and rearranging the thermometers (press the mouse button on the title bar to get a menu which includes "edit".  Use the same menu to return to "operate").
  422. '!
  423.  
  424.  
  425. !CFKDemo methodsFor: 'initialize-release'!
  426.  
  427. create
  428.     | c f k c1 tc tf tk tcf tck mpc |
  429.     Transcript cr; show: 'Building the ', self class name, '..'.
  430.     Transcript cr; show: '..adding the Fahrenheit thermometer'.
  431.     f _ ThermometerGlyph new initialize.
  432.     f moveTo: 50 @ 160.
  433.     f overVal: 752.0 underVal: -184.0.
  434.     self addGlyph: f.
  435.     Transcript cr; show: '..adding the Celsius thermometer'.
  436.     c _ ThermometerGlyph new initialize.
  437.     c moveTo: 250 @ 160.
  438.     c overVal: 400.0 underVal: -120.0.
  439.     self addGlyph: c.
  440.     Transcript cr; show: '..adding the Kelvin thermometer'.
  441.     k _ ThermometerGlyph new initialize.
  442.     k moveTo: 450 @ 160.
  443.     k minVal: 0.
  444.     k maxVal: 400.
  445.     k overVal: 450.0 underVal: -1.0.
  446.     self addGlyph: k.
  447.     Transcript cr; show: '..adding the consistency constraints'.
  448.     c1 _ Constraint names: #(c f ) methods: #('c _ (f - 32.0) / 1.8' 'f _ (c * 1.8) + 32' ).
  449.     c1
  450.         var: c temperatureVar
  451.         var: f temperatureVar
  452.         strength: #required.
  453.     c1 _ Constraint names: #(c k ) methods: #('c _ k - 273.16' 'k _ c + 273.16' ).
  454.     c1
  455.         var: c temperatureVar
  456.         var: k temperatureVar
  457.         strength: #required.
  458.     Transcript cr; show: '..adding the text boxes'.
  459.     tc _ TextGlyph new initialize.
  460.     tc text: 'Celsius'.
  461.     self addGlyph: tc.
  462.     tf _ TextGlyph new initialize.
  463.     tf text: 'Fahrenheit'.
  464.     self addGlyph: tf.
  465.     tk _ TextGlyph new initialize.
  466.     tk text: 'Kelvin'.
  467.     self addGlyph: tk.
  468.     tcf _ TwoProngTextGlyph new initialize.
  469.     tcf moveTo: 150 @ 325.
  470.     tcf
  471.         left: f editBox rightVar @ f editBox bottomVar
  472.         right: c editBox leftVar @ c editBox bottomVar
  473.         string: 'c * 1.8 = f - 32'.
  474.     self addGlyph: tcf.
  475.     tck _ TwoProngTextGlyph new initialize.
  476.     tck moveTo: 350 @ 325.
  477.     tck
  478.         left: c editBox rightVar @ c editBox bottomVar
  479.         right: k editBox leftVar @ k editBox bottomVar
  480.         string: 'k = c + 273.16'.
  481.     self addGlyph: tck.
  482.     Transcript cr; show: '..adding the layout constraints'.
  483.     EqualityConstraint
  484.         var: c editBox center xVar
  485.         var: tc box center xVar
  486.         strength: #required.
  487.     OffsetConstraint
  488.         from: c editBox bottomVar
  489.         to: tc box topVar
  490.         require: 30.
  491.     EqualityConstraint
  492.         var: f editBox center xVar
  493.         var: tf box center xVar
  494.         strength: #required.
  495.     OffsetConstraint
  496.         from: f editBox bottomVar
  497.         to: tf box topVar
  498.         require: 30.
  499.     EqualityConstraint
  500.         var: k editBox center xVar
  501.         var: tk box center xVar
  502.         strength: #required.
  503.     OffsetConstraint
  504.         from: k editBox bottomVar
  505.         to: tk box topVar
  506.         require: 30.
  507.     Transcript cr; show: 'finished'!
  508.  
  509. create1
  510.     | c f k c1 |
  511.     c _ ThermometerGlyph new initialize.
  512.     c moveTo: 30 @ 160.
  513.     f _ ThermometerGlyph new initialize.
  514.     f moveTo: 90 @ 160.
  515.     k _ ThermometerGlyph new initialize.
  516.     k moveTo: 150 @ 160.
  517.     k minVal: 0.
  518.     k maxVal: 400.
  519.     self addGlyph: c; addGlyph: f; addGlyph: k.
  520.     c1 _ Constraint names: #(c f ) methods: #('c _ (f - 32.0) / 1.8' 'f _ (c * 1.8) + 32' ).
  521.     c1
  522.         var: c temperatureVar
  523.         var: f temperatureVar
  524.         strength: #required.
  525.     c1 _ Constraint names: #(c k ) methods: #('c _ k - 273.16' 'k _ c + 273.16' ).
  526.     c1
  527.         var: c temperatureVar
  528.         var: k temperatureVar
  529.         strength: #required!
  530.  
  531. create2
  532.     | c f k c1 tc tf tk tcf tck mpc |
  533.     Transcript cr; show: 'Building the CFKDemo..'.
  534.     Transcript cr; show: '..adding the Fahrenheit thermometer'.
  535.     f _ ThermometerGlyph new initialize.
  536.     f moveTo: 50 @ 160.
  537.     self addGlyph: f.
  538.     Transcript cr; show: '..adding the Celsius thermometer'.
  539.     c _ ThermometerGlyph new initialize.
  540.     c moveTo: 250 @ 160.
  541.     self addGlyph: c.
  542.     Transcript cr; show: '..adding the Kelvin thermometer'.
  543.     k _ ThermometerGlyph new initialize.
  544.     k moveTo: 450 @ 160.
  545.     k minVal: 0.
  546.     k maxVal: 400.
  547.     self addGlyph: k.
  548.     Transcript cr; show: '..adding the consistency constraints'.
  549.     c1 _ Constraint names: #(c f ) methods: #('c _ (f - 32.0) / 1.8' 'f _ (c * 1.8) + 32' ).
  550.     c1
  551.         var: c temperatureVar
  552.         var: f temperatureVar
  553.         strength: #required.
  554.     c1 _ Constraint names: #(c k ) methods: #('c _ k - 273.16' 'k _ c + 273.16' ).
  555.     c1
  556.         var: c temperatureVar
  557.         var: k temperatureVar
  558.         strength: #required.
  559.     Transcript cr; show: '..adding the text boxes'.
  560.     tc _ TextGlyph new initialize.
  561.     tc text: 'Celsius'.
  562.     self addGlyph: tc.
  563.     tf _ TextGlyph new initialize.
  564.     tf text: 'Fahrenheit'.
  565.     self addGlyph: tf.
  566.     tk _ TextGlyph new initialize.
  567.     tk text: 'Kelvin'.
  568.     self addGlyph: tk.
  569.     tcf _ TextGlyph new initialize.
  570.     tcf text: 'c * 1.8 = f - 32'.
  571.     tcf moveTo: 150@160.
  572.     self addGlyph: tcf.
  573.     tck _ TextGlyph new initialize.
  574.     tck text: 'k = c + 273.16'.
  575.     tck moveTo: 350@160.
  576.     self addGlyph: tck.
  577.     Transcript cr; show: '..adding the layout constraints'.
  578.     EqualityConstraint
  579.         var: c editBox center xVar
  580.         var: tc box center xVar
  581.         strength: #required.
  582.     OffsetConstraint
  583.         from: c editBox bottomVar
  584.         to: tc box topVar
  585.         require: 30.
  586.     EqualityConstraint
  587.         var: f editBox center xVar
  588.         var: tf box center xVar
  589.         strength: #required.
  590.     OffsetConstraint
  591.         from: f editBox bottomVar
  592.         to: tf box topVar
  593.         require: 30.
  594.     EqualityConstraint
  595.         var: k editBox center xVar
  596.         var: tk box center xVar
  597.         strength: #required.
  598.     OffsetConstraint
  599.         from: k editBox bottomVar
  600.         to: tk box topVar
  601.         require: 30.
  602.     mpc _ Constraint names: #(p1 mp p2 ) methods: #('mp _ (p1 + p2) / 2' 'p1 _ mp*2 - p2' 'p2 _ mp*2 - p1' ).
  603.     mpc copy
  604.         var: c editBox bottomVar
  605.         var: tcf box bottomVar
  606.         var: f editBox bottomVar
  607.         strength: #required.
  608.     mpc copy
  609.         var: c editBox leftVar
  610.         var: tcf box leftVar
  611.         var: f editBox leftVar
  612.         strength: #required.
  613.     mpc copy
  614.         var: c editBox bottomVar
  615.         var: tck box bottomVar
  616.         var: k editBox bottomVar
  617.         strength: #required.
  618.     mpc copy
  619.         var: c editBox leftVar
  620.         var: tck box leftVar
  621.         var: k editBox leftVar
  622.         strength: #required.
  623.     StayConstraint var: c editBox leftVar strength: #default.
  624.     StayConstraint var: f editBox leftVar strength: #default.
  625.     StayConstraint var: k editBox leftVar strength: #default.
  626.     StayConstraint var: c editBox bottomVar strength: #default.
  627.     StayConstraint var: f editBox bottomVar strength: #default.
  628.     StayConstraint var: k editBox bottomVar strength: #default.
  629.     Transcript cr; show: 'finished'!
  630.  
  631. create3
  632.     | c f k c1 tc tf tk tcf tck mpc |
  633.     Transcript cr; show: 'Building the CFKDemo..'.
  634.     Transcript cr; show: '..adding the Fahrenheit thermometer'.
  635.     f _ ThermometerGlyph new initialize.
  636.     f moveTo: 50 @ 160.
  637.     self addGlyph: f.
  638.     Transcript cr; show: '..adding the Celsius thermometer'.
  639.     c _ ThermometerGlyph new initialize.
  640.     c moveTo: 250 @ 160.
  641.     self addGlyph: c.
  642.     Transcript cr; show: '..adding the Kelvin thermometer'.
  643.     k _ ThermometerGlyph new initialize.
  644.     k moveTo: 450 @ 160.
  645.     k minVal: 0.
  646.     k maxVal: 400.
  647.     self addGlyph: k.
  648.     Transcript cr; show: '..adding the consistency constraints'.
  649.     c1 _ Constraint names: #(c f ) methods: #('c _ (f - 32.0) / 1.8' 'f _ (c * 1.8) + 32' ).
  650.     c1
  651.         var: c temperatureVar
  652.         var: f temperatureVar
  653.         strength: #required.
  654.     c1 _ Constraint names: #(c k ) methods: #('c _ k - 273.16' 'k _ c + 273.16' ).
  655.     c1
  656.         var: c temperatureVar
  657.         var: k temperatureVar
  658.         strength: #required.
  659.     Transcript cr; show: '..adding the text boxes'.
  660.     tc _ TextGlyph new initialize.
  661.     tc text: 'Celsius'.
  662.     self addGlyph: tc.
  663.     tf _ TextGlyph new initialize.
  664.     tf text: 'Fahrenheit'.
  665.     self addGlyph: tf.
  666.     tk _ TextGlyph new initialize.
  667.     tk text: 'Kelvin'.
  668.     self addGlyph: tk.
  669.     tcf _ TextGlyph new initialize.
  670.     tcf text: 'c * 1.8 = f - 32'.
  671.     tcf moveTo: 150@260.
  672.     self addGlyph: tcf.
  673.     tck _ TextGlyph new initialize.
  674.     tck text: 'k = c + 273.16'.
  675.     tck moveTo: 350@260.
  676.     self addGlyph: tck.
  677.     Transcript cr; show: '..adding the layout constraints'.
  678.     EqualityConstraint
  679.         var: c editBox center xVar
  680.         var: tc box center xVar
  681.         strength: #required.
  682.     OffsetConstraint
  683.         from: c editBox bottomVar
  684.         to: tc box topVar
  685.         require: 30.
  686.     EqualityConstraint
  687.         var: f editBox center xVar
  688.         var: tf box center xVar
  689.         strength: #required.
  690.     OffsetConstraint
  691.         from: f editBox bottomVar
  692.         to: tf box topVar
  693.         require: 30.
  694.     EqualityConstraint
  695.         var: k editBox center xVar
  696.         var: tk box center xVar
  697.         strength: #required.
  698.     OffsetConstraint
  699.         from: k editBox bottomVar
  700.         to: tk box topVar
  701.         require: 30.
  702.     StayConstraint var: c editBox leftVar strength: #default.
  703.     StayConstraint var: f editBox leftVar strength: #default.
  704.     StayConstraint var: k editBox leftVar strength: #default.
  705.     StayConstraint var: c editBox bottomVar strength: #default.
  706.     StayConstraint var: f editBox bottomVar strength: #default.
  707.     StayConstraint var: k editBox bottomVar strength: #default.
  708.     mpc _ Constraint names: #(p1 mp p2 ) methods: #('mp _ (p1 + p2) / 2' 'p1 _ mp*2 - p2' 'p2 _ mp*2 - p1' ).
  709.     mpc copy
  710.         var: c editBox bottomVar
  711.         var: tcf box bottomVar
  712.         var: f editBox bottomVar
  713.         strength: #required.
  714.     mpc copy
  715.         var: c editBox leftVar
  716.         var: tcf box leftVar
  717.         var: f editBox leftVar
  718.         strength: #required.
  719.     mpc copy
  720.         var: c editBox bottomVar
  721.         var: tck box bottomVar
  722.         var: k editBox bottomVar
  723.         strength: #required.
  724.     mpc copy
  725.         var: c editBox leftVar
  726.         var: tck box leftVar
  727.         var: k editBox leftVar
  728.         strength: #required.
  729.     Transcript cr; show: 'finished'!
  730.  
  731. initialize
  732.     super initialize.
  733.     self create! !
  734.  
  735. !CFKDemo methodsFor: 'public'!
  736.  
  737. open
  738.     "CFKDemo new open"
  739.  
  740.     | topView |
  741.     topView _ SpecialSystemView
  742.                 model: nil
  743.                 label: 'Fahrenheit - Celsius - Kelvin Demo'
  744.                 minimumSize: 525 @ 400.
  745.     topView borderWidth: 1; addSubView: (SceneView new initialize model: self).
  746.     topView controller open! !
  747. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  748.  
  749. CFKDemo class
  750.     instanceVariableNames: ''!
  751.  
  752.  
  753. !CFKDemo class methodsFor: 'access'!
  754.  
  755. infoSize
  756.     ^700@310! !
  757.  
  758. Scene subclass: #AnchorLine1Demo
  759.     instanceVariableNames: ''
  760.     classVariableNames: ''
  761.     poolDictionaries: ''
  762.     category: 'Minstrel-SIGGRAPH'!
  763. AnchorLine1Demo comment:
  764. '                                        ***** What is a Constraint Hierarchy? (Anchors and Mice) *****
  765.  
  766. A constraint hierarchy is an ordered sequence of sets of constraints such that the constraints in the stronger sets dominate those in the weaker sets.  For example, if "X = 5" is strong and "X = 3" is weak, the solution would be "X = 5".  The strongest set in a constraint hierarchy is the required level: these constraints must be satisified.  All other levels are preferred and should be satisfied (respecting their various strengths) may be violated if necessary.
  767.  
  768. These three examples demonstrate different constraint hierarchies.  In the no-anchor example, the only constraints are the "horizontal line" constraint and (when the mouse drags a point) the "mouse drags point" constraint.  (Note: all interactions are implemented using constraints, thus the connection between the mouse and the point it is dragging is actually a constraint.)  In the anchor example, there is a strong "anchor" constraint which holds the left point in place.  This anchor constraint is stronger than the mouse constraint, and thus the mouse cannot move the left end and it can only move the right end back and forth.  In the anchor-strong-mouse example, the mouse has been made stronger than the anchor and thus the mouse can drag the anchor around again.
  769.  
  770. To summarize, the three examples have the following constraint hierarchies:
  771.         * no-anchor *                                * anchor *                                * anchor-strong-mouse *
  772.     required horizontal line                        required horizontal line                        required horizontal line
  773.     medium mouse                                strong anchor                                veryStrong mouse
  774.                                                 medium mouse                                strong anchor
  775. '!
  776.  
  777.  
  778. !AnchorLine1Demo methodsFor: 'initialize-release'!
  779.  
  780. create
  781.     | l |
  782.     Transcript cr; show: 'Building the ' , self class name , '..'.
  783.     Transcript cr; show: '..adding the components'.
  784.     l _ LineGlyph new.
  785.     l moveTo: 100 @ 100.
  786.     self addGlyph: l.
  787.     Transcript cr; show: '..adding the consistency constraints'.
  788.     EqualityConstraint
  789.         var: l p1 yVar
  790.         var: l p2 yVar
  791.         strength: #required.
  792.     Transcript cr; show: 'finished'!
  793.  
  794. initialize
  795.     super initialize.
  796.     self create! !
  797.  
  798. !AnchorLine1Demo methodsFor: 'public'!
  799.  
  800. open
  801.     "AnchorLine1Demo new open"
  802.  
  803.     | topView |
  804.     topView _ SpecialSystemView
  805.                 model: nil
  806.                 label: 'Horizontal Line, No Anchor'
  807.                 minimumSize: 300 @ 200.
  808.     topView borderWidth: 1; addSubView: (SceneView new initialize model: self).
  809.     topView controller open! !
  810. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  811.  
  812. AnchorLine1Demo class
  813.     instanceVariableNames: ''!
  814.  
  815.  
  816. !AnchorLine1Demo class methodsFor: 'access'!
  817.  
  818. infoSize
  819.     ^900@270! !
  820.  
  821. SceneView subclass: #MacDrawDemoView
  822.     instanceVariableNames: ''
  823.     classVariableNames: ''
  824.     poolDictionaries: ''
  825.     category: 'Minstrel-SIGGRAPH'!
  826.  
  827.  
  828. !MacDrawDemoView methodsFor: 'controller access'!
  829.  
  830. defaultControllerClass
  831.     ^MacDrawDemoController! !
  832.  
  833.  
  834. !FreeVariable methodsFor: 'access'!
  835.  
  836. speciallast
  837.     "Turn myself into a HistoryVariable and then return my previous state variable."
  838.  
  839.     | newSelf newLast |
  840.     newSelf _ HistoryVariable value: value.
  841.     newLast _ newSelf speciallast.
  842.     self become: newSelf.
  843.     ^newLast! !
  844.  
  845. Glyph subclass: #MacDrawRulerGlyph
  846.     instanceVariableNames: ''
  847.     classVariableNames: ''
  848.     poolDictionaries: ''
  849.     category: 'Minstrel-SIGGRAPH'!
  850.  
  851.  
  852. !MacDrawRulerGlyph methodsFor: 'glyph protocol'!
  853.  
  854. displayOn: aDisplayMedium at: aDisplayPoint clip: clipBox 
  855.     | left right bottom littles |
  856.     left _ MacDrawDemo leftEdge.
  857.     right _ MacDrawDemo rightEdge.
  858.     bottom _ MacDrawDemo dragTop - 20.
  859.     littles _ Array
  860.                 with: (Array with: 12.5 with: bottom - 5)
  861.                 with: (Array with: 25 with: bottom - 10)
  862.                 with: (Array with: 100 with: bottom - 25).
  863.     self
  864.         hLineFrom: left @ bottom
  865.         length: right - left
  866.         on: aDisplayMedium
  867.         at: aDisplayPoint
  868.         clip: clipBox.
  869.     littles do: [:each | left
  870.             to: right
  871.             by: (each at: 1)
  872.             do: [:x | self
  873.                     vLineFrom: x @ (each at: 2)
  874.                     length: bottom - (each at: 2)
  875.                     on: aDisplayMedium
  876.                     at: aDisplayPoint
  877.                     clip: clipBox]]!
  878.  
  879. isSelectable
  880.     ^false!
  881.  
  882. locationPoints
  883.     ^Array with: MacDrawDemo leftEdge @ MacDrawDemo dragTop! !
  884. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  885.  
  886. MacDrawRulerGlyph class
  887.     instanceVariableNames: ''!
  888.  
  889.  
  890. !MacDrawRulerGlyph class methodsFor: 'classification'!
  891.  
  892. glyphCategory
  893.     ^'SIGGRAPH'! !
  894.  
  895.  
  896. !VectorGlyph methodsFor: 'initialize-release'!
  897.  
  898. addConstraints
  899.  
  900.     (ArrowC isNil) ifTrue:
  901.         [ArrowC _ Constraint
  902.             names: #(vector p1 p2)
  903.             methods: #('vector _ p2 - p1')].
  904.     (DirectionC isNil) ifTrue:
  905.         [DirectionC _ Constraint
  906.             names: #(p1 p2 oldP1 oldP2)
  907.             methods: #('p2 _ p1 + (oldP2 - oldP1)')].
  908.  
  909.     "constraints to attach and align arrow head"
  910.     (p2 xVar) requireEquals: (arrowHead location xVar).
  911.     (p2 yVar) requireEquals: (arrowHead location yVar).
  912.     (ArrowC copy) var: (arrowHead vector xVar) var: (p1 xVar) var: (p2 xVar) strength: #required.
  913.     (ArrowC copy) var: (arrowHead vector yVar) var: (p1 yVar) var: (p2 yVar) strength: #required.
  914.  
  915.     "constraints to maintain vector length and direction when moving p1"
  916.     (DirectionC copy)
  917.         var: (p1 xVar) var: (p2 xVar)
  918.         var: (p1 xVar last) var: (p2 xVar last) strength: #default.
  919.     (DirectionC copy)
  920.         var: (p1 yVar) var: (p2 yVar)
  921.         var: (p1 yVar last) var: (p2 yVar last) strength: #default.! !
  922.  
  923. Scene subclass: #AnchorLine3Demo
  924.     instanceVariableNames: ''
  925.     classVariableNames: ''
  926.     poolDictionaries: ''
  927.     category: 'Minstrel-SIGGRAPH'!
  928.  
  929.  
  930. !AnchorLine3Demo methodsFor: 'initialize-release'!
  931.  
  932. create
  933.     | l f |
  934.     Transcript cr; show: 'Building the ' , self class name , '..'.
  935.     Transcript cr; show: '..adding the components'.
  936.     f _ SIGGRAPHAnchorGlyph new initialize.
  937.     l _ LineGlyph new.
  938.     l moveTo: 100 @ 100.
  939.     self addGlyph: f; addGlyph: l.
  940.     Transcript cr; show: '..adding the consistency constraints'.
  941.     EqualityConstraint
  942.         var: l p1 yVar
  943.         var: l p2 yVar
  944.         strength: #required.
  945.     EqualityConstraint
  946.         var: l p1 xVar
  947.         var: f xVar
  948.         strength: #required.
  949.     EqualityConstraint
  950.         var: l p1 yVar
  951.         var: f yVar
  952.         strength: #required.
  953.     StayConstraint var: f xVar strength: #default.
  954.     StayConstraint var: f yVar strength: #default.
  955.     Transcript cr; show: 'finished'!
  956.  
  957. initialize
  958.     super initialize.
  959.     self create! !
  960.  
  961. !AnchorLine3Demo methodsFor: 'public'!
  962.  
  963. open
  964.     "AnchorLine3Demo new open"
  965.  
  966.     | topView |
  967.     topView _ SpecialSystemView
  968.                 model: nil
  969.                 label: 'Horizontal Line, Anchor, Strong Mouse'
  970.                 minimumSize: 300 @ 200.
  971.     topView borderWidth: 1; addSubView: (SceneView new initialize model: self).
  972.     topView controller open! !
  973. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  974.  
  975. AnchorLine3Demo class
  976.     instanceVariableNames: ''!
  977.  
  978.  
  979.  
  980. !HistoryVariable methodsFor: 'history'!
  981.  
  982. speciallast
  983.     "Answer the DBVariable for my previous state. If there isn't one yet, create one and remember it."
  984.  
  985.     (last == nil) ifTrue:
  986.         [last _ HistoryVariable value: value.
  987.          last walkStrength: Strength absoluteWeakest.
  988.          last stay: false].
  989.     ^last! !
  990.  
  991. Scene subclass: #Plus1Demo
  992.     instanceVariableNames: 'values '
  993.     classVariableNames: 'PlusConstraint PrintConstraint '
  994.     poolDictionaries: ''
  995.     category: 'Minstrel-SIGGRAPH'!
  996. Plus1Demo comment:
  997. '                                ***** Why use Constraint Hierarchies? (Sums) *****
  998.  
  999. Constraint hierarchies are useful for many parts of a software system including: (i) as a declarative specification for defaults, (ii) as a mechanism to describe the behavior of a graphical user interface, and (iii) as a mechanism for declaratively controlling the dataflow.  Typically, to control the flow of data in a "flat" constraint system one must use some operational features.  For example, many constraint system use a well-defined search mechanism and thus the user can write his or her rules to take advantage of that mechanism to control the dataflow, i.e., he or she can use non-declarative features.  Of course, if the system is improved and the search algorithm changes, the program no longer works correctly.  One of the benefits of using a constraint hierarchy is that the hierarchy can control the dataflow declaratively.
  1000.  
  1001. The no-hierarchy demo has a flat constraint system and just a little experimentation will illustrate that its behavior is difficult to predict.  Specifically, the data does not flow from left-to-right as one might expect.  The hierarchy demo uses constraints of different strengths to cause the "correct" dataflow.  Furthermore, any constraint hierarchy solver will produce exactly the same solutions for this second demo, regardless of its implementation (assuming, of course, that the solver is implemented correctly.)
  1002. '!
  1003.  
  1004.  
  1005. !Plus1Demo methodsFor: 'initialize-release'!
  1006.  
  1007. create
  1008.     "Plus1Demo releaseConstraints"
  1009.  
  1010.     | texts xs ys ps |
  1011.     Transcript cr; show: 'Building the ' , self class name , '..'.
  1012.     Transcript cr; show: '..adding the components'.
  1013.     values _ Array new: 7.
  1014.     1 to: values size do: [:i | values at: i put: (FreeVariable value: 10)].
  1015.     texts _ Array new: values size.
  1016.     1 to: values size do: [:i | texts at: i put: BoxTextGlyph new].
  1017.     xs _ #(50 50 150 150 250 250 350 ).
  1018.     ys _ #(50 150 100 200 150 250 200 ).
  1019.     ps _ OrderedCollection new.
  1020.     xs with: ys do: [:x :y | ps add: x @ y].
  1021.     texts with: ps do: 
  1022.         [:text :p | 
  1023.         text moveTo: p].
  1024.     xs _ #(100 200 300 ).
  1025.     ys _ #(100 150 200 ).
  1026.     1
  1027.         to: 5
  1028.         by: 2
  1029.         do: 
  1030.             [:i | 
  1031.             p _ ThreeProngTextGlyph new initialize.
  1032.             p
  1033.                 left: (texts at: i) center
  1034.                 right: (texts at: i + 2) center
  1035.                 down: (texts at: i + 1) center
  1036.                 string: '+'.
  1037.             self addGlyph: p].
  1038.     texts do: [:each | self addGlyph: each].
  1039.     Transcript cr; show: '..adding the consistency constraints'.
  1040.     PrintConstraint isNil ifTrue: [PrintConstraint _ Constraint names: #(text temp ) methods: #('temp _ text asNumber' 'text _ temp printString' )].
  1041.     texts with: values do: [:text :value | PrintConstraint copy
  1042.             var: text textVar
  1043.             var: value
  1044.             strength: #required].
  1045.     PlusConstraint isNil ifTrue: [PlusConstraint _ Constraint names: #(a b c ) methods: #('c _ a + b' 'a _ c - b' 'b _ c - a' )].
  1046.     1
  1047.         to: 5
  1048.         by: 2
  1049.         do: [:i | PlusConstraint copy
  1050.                 var: (values at: i)
  1051.                 var: (values at: i + 1)
  1052.                 var: (values at: i + 2)
  1053.                 strength: #required].
  1054.     self createDefaults.
  1055.     Transcript cr; show: 'finished'!
  1056.  
  1057. createDefaults!
  1058.  
  1059. initialize
  1060.     super initialize.
  1061.     self create! !
  1062.  
  1063. !Plus1Demo methodsFor: 'public'!
  1064.  
  1065. open
  1066.     "Plus1Demo new open"
  1067.  
  1068.     | topView |
  1069.     topView _ SpecialSystemView
  1070.                 model: nil
  1071.                 label: 'Plus Demo, No Hierarchy'
  1072.                 minimumSize: 400 @ 300.
  1073.     topView borderWidth: 1; addSubView: (SceneView new initialize model: self).
  1074.     topView controller open! !
  1075. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1076.  
  1077. Plus1Demo class
  1078.     instanceVariableNames: ''!
  1079.  
  1080.  
  1081. !Plus1Demo class methodsFor: 'constraint release'!
  1082.  
  1083. releaseConstraints
  1084.     "Plus1Demo releaseConstraints"
  1085.  
  1086.     PrintConstraint _ PlusConstraint _ nil! !
  1087.  
  1088. !Plus1Demo class methodsFor: 'access'!
  1089.  
  1090. infoSize
  1091.     ^700@250! !
  1092. PointGlyph subclass: #AnchorGlyph
  1093.     instanceVariableNames: 'node anchorForm '
  1094.     classVariableNames: 'AnchorForm '
  1095.     poolDictionaries: ''
  1096.     category: 'Minstrel-Springs Demo'!
  1097. Object subclass: #AbstractConstraint
  1098.     instanceVariableNames: 'strength name '
  1099.     classVariableNames: ''
  1100.     poolDictionaries: ''
  1101.     category: 'DB-Constraints'!
  1102.  
  1103.  
  1104. !AbstractConstraint methodsFor: 'accessing'!
  1105.  
  1106. name: n
  1107.     name _ n! !
  1108.  
  1109. !AbstractConstraint methodsFor: 'printing'!
  1110.  
  1111. longPrintOn: aStream
  1112.  
  1113.     | bindings |
  1114.     aStream nextPut: $(.
  1115.     self shortPrintOn: aStream.
  1116.     aStream space; nextPutAll: self strength printString.
  1117.     (self isSatisfied)
  1118.         ifTrue:
  1119.             [aStream cr; space; space; space.
  1120.              self inputsDo:
  1121.                 [: in | aStream nextPutAll: 'v', in asOop printString, '(', in value printString, ') '].
  1122.             aStream nextPutAll: '-> '.
  1123.             aStream nextPutAll: 'v', self output asOop printString, '(', self output value printString, ')']
  1124.         ifFalse:
  1125.             [aStream space; nextPutAll: 'UNSATISFIED'].
  1126.     aStream nextPut: $)!
  1127.  
  1128. shortPrintOn: aStream
  1129.  
  1130.     aStream nextPutAll: self class name.
  1131.     aStream nextPutAll: '(', self asOop printString.
  1132.     name notNil ifTrue: [aStream nextPutAll: ' "', name, '"'].
  1133.     aStream nextPut: $)! !
  1134.  
  1135. ScriptGlyph subclass: #ThreeProngTextGlyph
  1136.     instanceVariableNames: 'textGlyph left right down offset '
  1137.     classVariableNames: 'CenterOffsetConstraint '
  1138.     poolDictionaries: ''
  1139.     category: 'Minstrel-SIGGRAPH'!
  1140.  
  1141.  
  1142. !ThreeProngTextGlyph methodsFor: 'initialize-release'!
  1143.  
  1144. initialize
  1145.     "ThreeProngTextGlyph releaseConstraints"
  1146.  
  1147.     super initialize.
  1148.     textGlyph _ TextGlyph new initialize.
  1149.     left _ PointGlyph new initialize.
  1150.     right _ PointGlyph new initialize.
  1151.     down _ PointGlyph new initialize.
  1152.     left moveTo: 10 @ 10.
  1153.     right moveTo: 100 @ 10.
  1154.     down moveTo: 45@ 50.
  1155.     textGlyph moveTo: 40 @ 15.
  1156.     offset _ PointGlyph new initialize.
  1157.     offset moveTo: 0 @ 8.
  1158.     CenterOffsetConstraint isNil ifTrue: [CenterOffsetConstraint _ (Constraint names: #(out left right down off ) methods: #('out _ ((left + right + down) // 3) - off' 'off _ ((left + right + down) // 3) - out' ))
  1159.                     name: 'center offset'].
  1160.     StayConstraint
  1161.         var: offset xVar
  1162.         strength: #default.
  1163.     CenterOffsetConstraint copy
  1164.         var: textGlyph box leftVar
  1165.         var: left xVar
  1166.         var: right xVar
  1167.         var: down xVar
  1168.         var: offset xVar
  1169.         strength: #required.
  1170.     StayConstraint
  1171.         var: offset yVar
  1172.         strength: #default.
  1173.     CenterOffsetConstraint copy
  1174.         var: textGlyph box topVar
  1175.         var: left yVar
  1176.         var: right yVar
  1177.         var: down yVar
  1178.         var: offset yVar
  1179.         strength: #required!
  1180.  
  1181. left: l right: r down: d string: s
  1182.     | stays |  
  1183.     stays _ Set new.
  1184.     stays add: (StayConstraint
  1185.         var: "textGlyph box leftVar" offset xVar
  1186.         strength: #strongPreferred).
  1187.     stays add: (StayConstraint
  1188.         var: "textGlyph box topVar" offset yVar
  1189.         strength: #strongPreferred).
  1190.     stays add: (StayConstraint
  1191.         var: l xVar
  1192.         strength: #strongPreferred).
  1193.     stays add: (StayConstraint
  1194.         var: l yVar
  1195.         strength: #strongPreferred).
  1196.     stays add: (StayConstraint
  1197.         var: r xVar
  1198.         strength: #strongPreferred).
  1199.     stays add: (StayConstraint
  1200.         var: r yVar
  1201.         strength: #strongPreferred).
  1202.     stays add: (StayConstraint
  1203.         var: d xVar
  1204.         strength: #strongPreferred).
  1205.     stays add: (StayConstraint
  1206.         var: d yVar
  1207.         strength: #strongPreferred).
  1208.     EqualityConstraint
  1209.         var: l xVar
  1210.         var: left xVar
  1211.         strength: #required.
  1212.     EqualityConstraint
  1213.         var: l yVar
  1214.         var: left yVar
  1215.         strength: #required.
  1216.     EqualityConstraint
  1217.         var: r xVar
  1218.         var: right xVar
  1219.         strength: #required.
  1220.     EqualityConstraint
  1221.         var: r yVar
  1222.         var: right yVar
  1223.         strength: #required.
  1224.     EqualityConstraint
  1225.         var: d xVar
  1226.         var: down xVar
  1227.         strength: #required.
  1228.     EqualityConstraint
  1229.         var: d yVar
  1230.         var: down yVar
  1231.         strength: #required.
  1232.     stays do: [:each | each destroyConstraint].
  1233.     textGlyph text: s! !
  1234.  
  1235. !ThreeProngTextGlyph methodsFor: 'access'!
  1236.  
  1237. offset: p
  1238.     offset xVar value: p x.
  1239.     offset yVar value: p y! !
  1240.  
  1241. !ThreeProngTextGlyph methodsFor: 'glyph protocol'!
  1242.  
  1243. boundingBox
  1244.     ^textGlyph boundingBox!
  1245.  
  1246. displayOn: aDisplayMedium at: aDisplayPoint clip: clipBox 
  1247.     | r |
  1248.     r _ textGlyph box asRectangle moveBy: aDisplayPoint.
  1249.     (Line
  1250.         from: left asPoint
  1251.         to: r left @ r top
  1252.         withForm: (Form extent: 1 @ 1) black)
  1253.         displayOn: aDisplayMedium
  1254.         at: aDisplayPoint.
  1255.     (Line
  1256.         from: right asPoint
  1257.         to: r right @ r center y
  1258.         withForm: (Form extent: 1 @ 1) black)
  1259.         displayOn: aDisplayMedium
  1260.         at: aDisplayPoint.
  1261.     (Line
  1262.         from: down asPoint
  1263.         to: r left @ r bottom
  1264.         withForm: (Form extent: 1 @ 1) black)
  1265.         displayOn: aDisplayMedium
  1266.         at: aDisplayPoint.
  1267.     aDisplayMedium fill: (r insetBy: -1 @ -1) mask: Form white.
  1268.     textGlyph
  1269.         displayOn: aDisplayMedium
  1270.         at: aDisplayPoint
  1271.         clip: clipBox.
  1272.     aDisplayMedium border: (r insetBy: -3 @ -3)
  1273.         width: 2 mask: Form gray.
  1274.     false ifTrue: [self stilltodo]!
  1275.  
  1276. isSelectable
  1277.     ^true!
  1278.  
  1279. locationPoints
  1280.     ^Array
  1281.         with: textGlyph box center"
  1282.         with: left asPoint
  1283.         with: right asPoint
  1284.         with: down asPoint"! !
  1285.  
  1286. !ThreeProngTextGlyph methodsFor: 'enumeration'!
  1287.  
  1288. selectableGlyphsDo: aBlock 
  1289.     aBlock value: self.
  1290.     aBlock value: textGlyph.
  1291. "aBlock value: left.
  1292. aBlock value: right.
  1293. aBlock value: down"!
  1294.  
  1295. visibleGlyphsDo: aBlock 
  1296.     aBlock value: self.
  1297.     aBlock value: textGlyph! !
  1298. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1299.  
  1300. ThreeProngTextGlyph class
  1301.     instanceVariableNames: ''!
  1302.  
  1303.  
  1304. !ThreeProngTextGlyph class methodsFor: 'classification'!
  1305.  
  1306. glyphCategory
  1307.     ^'SIGGRAPH'! !
  1308.  
  1309. !ThreeProngTextGlyph class methodsFor: 'constraint release'!
  1310.  
  1311. releaseConstraints
  1312.     "ThreeProngTextGlyph releaseConstraints"
  1313.  
  1314.     CenterOffsetConstraint _ nil! !
  1315.  
  1316. ScriptGlyph subclass: #ThermometerGlyph
  1317.     instanceVariableNames: 'temperature minVal maxVal overVal over underVal under editBox mercury textGlyph editConstraint editConstraint2 plan prevY '
  1318.     classVariableNames: 'BulbForm BulbForm2 CapForm MercConstraint OverConstraint PrintConstraint UnderConstraint '
  1319.     poolDictionaries: ''
  1320.     category: 'Minstrel-SIGGRAPH'!
  1321.  
  1322.  
  1323. !ThermometerGlyph methodsFor: 'initialize-release'!
  1324.  
  1325. initialize
  1326.     super initialize.
  1327.     editBox _ (RectangleGlyph new) width: 20; height: 200.
  1328.     minVal _ FreeVariable value: -100.0.
  1329.     underVal _ FreeVariable value: -120.0.
  1330.     maxVal _ FreeVariable value: 300.0.
  1331.     overVal _ FreeVariable value: 320.0.
  1332.     temperature _ FreeVariable value: 0.
  1333.     over _ FreeVariable value: false.
  1334.     under _ FreeVariable value: false.
  1335.     mercury _ PointGlyph new initialize.
  1336.     mercury moveTo: editBox center asPoint + editBox width asPoint.
  1337.     textGlyph _ TextGlyph new initialize.
  1338.     PrintConstraint isNil ifTrue: [PrintConstraint _ Constraint names: #(text temp ) methods: #('text _ temp printString' 'temp _ text asNumber' )].
  1339.     PrintConstraint copy
  1340.         var: textGlyph textVar
  1341.         var: temperature
  1342.         strength: #required.
  1343.     EqualityConstraint
  1344.         var: mercury yVar
  1345.         var: textGlyph box bottomVar
  1346.         strength: #required.
  1347.     "EqualityConstraint  
  1348.     var: mercury xVar  
  1349.     var: textGlyph box leftVar  
  1350.     strength: #required."
  1351.     EqualityConstraint
  1352.         var: editBox rightVar
  1353.         var: textGlyph box leftVar
  1354.         strength: #required.
  1355.     MercConstraint isNil ifTrue: [MercConstraint _ Constraint names: #(boxh boxt merc min max temp ) methods: #('merc _ ThermometerGlyph internalMsg1: min and: max and: temp and: boxh and: boxt' )].
  1356.     MercConstraint copy
  1357.         var: editBox heightVar
  1358.         var: editBox topVar
  1359.         var: mercury yVar
  1360.         var: minVal
  1361.         var: maxVal
  1362.         var: temperature
  1363.         strength: #required.
  1364.     OverConstraint isNil ifTrue: [OverConstraint _ Constraint names: #(temp over overval ) methods: #('over _ ThermometerGlyph internalMsg2: temp and: overval' )].
  1365.     OverConstraint copy
  1366.         var: temperature
  1367.         var: over
  1368.         var: overVal
  1369.         strength: #required.
  1370.     UnderConstraint isNil ifTrue: [UnderConstraint _ Constraint names: #(temp under underval ) methods: #('under _ ThermometerGlyph internalMsg3: temp and: underval' )].
  1371.     UnderConstraint copy
  1372.         var: temperature
  1373.         var: under
  1374.         var: underVal
  1375.         strength: #required! !
  1376.  
  1377. !ThermometerGlyph methodsFor: 'accessing'!
  1378.  
  1379. editBox
  1380.     ^editBox!
  1381.  
  1382. maxVal: aNumber 
  1383.     maxVal setValue: aNumber!
  1384.  
  1385. minVal: aNumber 
  1386.     minVal setValue: aNumber!
  1387.  
  1388. overVal: n underVal: m 
  1389.     overVal value: n.
  1390.     underVal value: m!
  1391.  
  1392. temperature
  1393.  
  1394.     ^temperature value!
  1395.  
  1396. temperature: aNumber
  1397.  
  1398.     temperature setValue: ((aNumber max: minVal value) min: maxVal value).!
  1399.  
  1400. temperatureVar
  1401.     ^temperature! !
  1402.  
  1403. !ThermometerGlyph methodsFor: 'glyph protocol'!
  1404.  
  1405. boundingBox
  1406.     | r left right top bottom bf |
  1407.     false ifTrue: [self stilltodo].
  1408.     bf _ under value
  1409.                 ifTrue: [BulbForm2]
  1410.                 ifFalse: [BulbForm].
  1411.     r _ editBox asRectangle.
  1412.     left _ r left - (bf width - r width // 2).
  1413.     right _ r right + (bf width - r width // 2).
  1414.     top _ r top.
  1415.     over value ifTrue: [top _ top - CapForm height].
  1416.     bottom _ r bottom + bf height.
  1417.     ^left @ top corner: right @ bottom!
  1418.  
  1419. displayOn: aDisplayMedium at: aDisplayPoint clip: clipBox 
  1420.     | markY box |
  1421.     box _ editBox asRectangle moveBy: aDisplayPoint.
  1422.     markY _ (editBox left @ mercury y) corner: editBox bottomRight.
  1423.     aDisplayMedium fill: editBox mask: Form white.
  1424.     aDisplayMedium fill: markY mask: Form gray.
  1425.     aDisplayMedium border: editBox asRectangle width: 1.
  1426.     under value
  1427.         ifTrue: [BulbForm2 displayOn: aDisplayMedium at: editBox bottomLeft - (0 @ 1) - (BulbForm2 width - editBox width // 2 @ 0)]
  1428.         ifFalse: [BulbForm displayOn: aDisplayMedium at: editBox bottomLeft - (0 @ 1) - (BulbForm width - editBox width // 2 @ 0)].
  1429.     over value ifTrue: [CapForm displayOn: aDisplayMedium at: editBox topLeft - (((CapForm width - editBox width // 2)) @ (CapForm height - 1))].
  1430.     false ifTrue: [self stilltodo]!
  1431.  
  1432. isSelectable
  1433.     ^true!
  1434.  
  1435. locationPoints
  1436.     ^Array with: editBox center!
  1437.  
  1438. old.displayOn: aDisplayMedium at: aDisplayPoint clip: clipBox 
  1439.     | scaleFactor markY over1 under1 |
  1440.     "textGlyph displayOn: aDisplayMedium at: aDisplayPoint clip: clipBox."
  1441.     scaleFactor _ editBox height asFloat / (maxVal value - minVal value) asFloat.
  1442.     markY _ (scaleFactor * (temperature value asFloat - minVal value asFloat)) rounded.
  1443.     over1 _ markY > (editBox height + 40).
  1444.     under1 _ markY < -60.
  1445.     markY _ (markY max: 0)
  1446.                 min: editBox height.
  1447.     markY _ editBox height - markY.
  1448.     markY _ editBox topLeft + (0 @ markY) corner: editBox bottomRight.
  1449.     aDisplayMedium fill: editBox mask: Form white.
  1450.     aDisplayMedium fill: markY mask: Form gray.
  1451.     aDisplayMedium border: editBox asRectangle width: 1.
  1452.     under1
  1453.         ifTrue: [BulbForm2 displayOn: aDisplayMedium at: editBox bottomLeft - (0 @ 1) - (BulbForm2 width - editBox width // 2 @ 0)]
  1454.         ifFalse: [BulbForm displayOn: aDisplayMedium at: editBox bottomLeft - (0 @ 1) - (BulbForm width - editBox width // 2 @ 0)].
  1455.     over1 ifTrue: [CapForm displayOn: aDisplayMedium at: editBox topLeft - (0 @ (CapForm height - 1))].
  1456.     false ifTrue: [self stilltodo]! !
  1457.  
  1458. !ThermometerGlyph methodsFor: 'enumeration'!
  1459.  
  1460. selectableGlyphsDo: aBlock 
  1461.     aBlock value: self.
  1462.     "aBlock value: mercury."
  1463.     aBlock value: textGlyph!
  1464.  
  1465. visibleGlyphsDo: aBlock
  1466.     aBlock value: self.
  1467.     "aBlock value: mercury."
  1468.     aBlock value: textGlyph! !
  1469.  
  1470. !ThermometerGlyph methodsFor: 'mouse'!
  1471.  
  1472. handleMouseDown: mousePoint view: view 
  1473.     Sensor leftShiftDown
  1474.         ifTrue: [^self editScript]
  1475.         ifFalse: 
  1476.             [editConstraint _ EditConstraint var: temperature strength: #preferred.
  1477.             editConstraint2 _ EditConstraint var: mercury yVar strength: #preferred.
  1478.             editConstraint isSatisfied
  1479.                 ifTrue: 
  1480.                     [plan _ Planner extractPlanFromInputConstraints: (Array with: editConstraint with: editConstraint2).
  1481.                     view computeBackground]
  1482.                 ifFalse: [view flash]]!
  1483.  
  1484. handleMouseMove: mousePoint view: view 
  1485.     "Move the slider, show feedback, and run the script. If the shift key is pressed, 
  1486.     the user wants to edit the script, so do nothing."
  1487.  
  1488.     | scaleFactor relativeY scaledValue |
  1489.     scaleFactor _ (maxVal value - minVal value) asFloat / editBox height asFloat.
  1490.     relativeY _ mousePoint y - editBox top.
  1491.     relativeY _ relativeY max: 0.
  1492.     relativeY _ relativeY min: editBox height.
  1493.     relativeY _ editBox height - relativeY.
  1494.     (relativeY ~~ prevY and: [editConstraint notNil and: [editConstraint isSatisfied]])
  1495.         ifTrue: 
  1496.             [scaledValue _ minVal value asFloat + (scaleFactor * relativeY asFloat).
  1497.             temperature value: scaledValue.
  1498.             mercury yVar value: (editBox height - relativeY)  + (editBox top).
  1499.             plan execute.
  1500.             view displayFeedback.
  1501.             compiledScript notNil ifTrue: [compiledScript
  1502.                     value: view model
  1503.                     value: view
  1504.                     value: scaledValue].
  1505.             prevY _ relativeY]!
  1506.  
  1507. handleMouseUp: mousePoint view: view 
  1508.     "Clean up the edit constraint and plan."
  1509.  
  1510.     editConstraint notNil
  1511.         ifTrue: 
  1512.             [editConstraint destroyConstraint.
  1513.             editConstraint _ nil.
  1514.             editConstraint2 destroyConstraint.
  1515.             editConstraint2 _ nil.
  1516.             plan release.
  1517.             plan _ nil]!
  1518.  
  1519. wantsMouse
  1520.     ^true! !
  1521. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1522.  
  1523. ThermometerGlyph class
  1524.     instanceVariableNames: ''!
  1525.  
  1526.  
  1527. !ThermometerGlyph class methodsFor: 'class initialization'!
  1528.  
  1529. initialize
  1530.     "ThermometerGlyph initialize."
  1531.  
  1532.     BulbForm _ Form
  1533.                 extent: 30 @ 30
  1534.                 fromArray: #(1706 43712 1365 21824 1706 43712 1365 21824 1706 43712 3413 21856 6826 43696 13653 21840 10922 43704 13653 21848 10922 43688 30037 21852 27306 43692 54613 21844 43690 43692 54613 21844 60074 43692 21845 21844 27306 43692 13653 21848 10922 43704 13653 21840 6826 43696 3413 21856 1706 43712 853 21888 426 43776 213 22016 127 64512 0 0 )
  1535.                 offset: 0 @ 0.
  1536.     BulbForm2 _ (Form
  1537.     extent: 30@30
  1538.     fromArray: #( 1706 43712 1365 21824 1706 43712 1365 21824 1706 43712 3413 21856 6826 43696 13653 21840 10922 43704 13653 22520 10922 43520 30079 22016 27361 44032 57281 22528 43009 45060 55296 57356 59392 796 22648 2036 29167 3756 341 40280 938 64184 8021 21840 6826 43696 3413 21856 1706 43712 853 21888 426 43776 213 22016 127 64512 0 0)
  1539.     offset: 0@0).
  1540.     CapForm _ (Form
  1541.     extent: 41@29
  1542.     fromArray: #( 0 0 0 0 0 0 32263 33249 61184 32527 50161 65280 25500 59193 47872 24984 26137 47872 25496 26137 33536 32536 26137 33536 32536 26137 33536 25496 26137 33536 24984 26137 33536 25500 59161 33536 32527 50161 33536 32263 33249 33536 0 0 0 43176 2082 35328 21585 21765 5376 43682 43690 10752 5461 17749 21504 2730 2600 43008 4437 21841 21504 674 43690 32768 341 21781 16384 682 43690 40960 341 17749 16384 42 43688 0 85 21844 0 10 43688 0 21 21844 0)
  1543.     offset: 0@0)! !
  1544.  
  1545. !ThermometerGlyph class methodsFor: 'internal'!
  1546.  
  1547. internalMsg1: minVar and: maxVar and: tempVar and: boxHeightVar and: boxTopVar
  1548.     | scaleFactor markY |
  1549.     scaleFactor _ boxHeightVar  asFloat / (maxVar  - minVar ) asFloat.
  1550.     markY _ (scaleFactor * (tempVar  asFloat - minVar  asFloat)) rounded.
  1551.     markY _ (markY max: 0)
  1552.                 min: boxHeightVar.
  1553.     markY _ boxHeightVar - markY + boxTopVar.
  1554.     ^markY!
  1555.  
  1556. internalMsg2: tempVar and: over
  1557.     ^tempVar > over!
  1558.  
  1559. internalMsg3: tempVar and: under
  1560.     ^tempVar < under! !
  1561.  
  1562. !ThermometerGlyph class methodsFor: 'constraint release'!
  1563.  
  1564. releaseConstraints
  1565.     "ThermometerGlyph releaseConstraints"
  1566.  
  1567.     PrintConstraint _ MercConstraint _ OverConstraint _ UnderConstraint _ nil! !
  1568.  
  1569. !ThermometerGlyph class methodsFor: 'classification'!
  1570.  
  1571. glyphCategory
  1572.     ^'SIGGRAPH'! !
  1573.  
  1574. ThermometerGlyph initialize!
  1575.  
  1576.  
  1577. PointGlyph subclass: #FakeMouseGlyph
  1578.     instanceVariableNames: 'form '
  1579.     classVariableNames: 'MouseForm '
  1580.     poolDictionaries: ''
  1581.     category: 'Minstrel-SIGGRAPH'!
  1582.  
  1583.  
  1584. !FakeMouseGlyph methodsFor: 'glyph protocol'!
  1585.  
  1586. displayOn: aDisplayMedium at: aDisplayPoint clip: clipBox 
  1587.     MouseForm
  1588.         displayOn: aDisplayMedium
  1589.         at: aDisplayPoint + self asPoint
  1590.         clippingBox: clipBox
  1591.         rule: Form paint
  1592.         mask: Form black! !
  1593.  
  1594. !FakeMouseGlyph methodsFor: 'merging'!
  1595.  
  1596. canMergeWith: aGlyph 
  1597.     ^false!
  1598.  
  1599. changing
  1600.     "This is a hack to prevent the ugly black can-merge box from showing up around 
  1601.     my anchor."
  1602.  
  1603.     ^true! !
  1604. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1605.  
  1606. FakeMouseGlyph class
  1607.     instanceVariableNames: ''!
  1608.  
  1609.  
  1610. !FakeMouseGlyph class methodsFor: 'class initialization'!
  1611.  
  1612. initialize
  1613.     "FakeMouseGlyph initialize"
  1614.  
  1615.     MouseForm _ Form
  1616.                 extent: 16 @ 16
  1617.                 fromArray: #(1 3 7 15 31 63 127 31 31 25 48 48 96 96 192 192 )
  1618.                 offset: -16 @ 0.! !
  1619.  
  1620. FakeMouseGlyph initialize!
  1621.  
  1622.  
  1623. Scene subclass: #TwoPlanetDemo
  1624.     instanceVariableNames: 'planet1 planet2 velocity1 velocity2 accel1 accel2 gravity '
  1625.     classVariableNames: ''
  1626.     poolDictionaries: ''
  1627.     category: 'Minstrel-SIGGRAPH'!
  1628.  
  1629.  
  1630. !TwoPlanetDemo methodsFor: 'initialize-release'!
  1631.  
  1632. create
  1633.     | v1 h1 v2 v3 v4 c cx cy |
  1634.     Transcript cr; show: 'Building the ' , self class name , '..'.
  1635.     Transcript cr; show: '..adding planets'.
  1636.     gravity _ FreeVariable new.
  1637.     planet1 _ PlanetGlyph new initialize.
  1638.     planet1 form2.
  1639.     planet1 moveTo: 150 @ 200.
  1640.     planet2 _ PlanetGlyph new initialize.
  1641.     planet2 form2b.
  1642.     planet2 moveTo: 350 @ 250.
  1643.     self addGlyph: planet1; addGlyph: planet2.
  1644.     Transcript cr; show: '..adding control sliders'.
  1645.     v1 _ PlanetVectorGlyph new initialize.
  1646.     v1 moveTo: 50 @ 50.
  1647.     v2 _ PlanetVectorGlyph new initialize.
  1648.     v2 moveTo: 125 @ 50.
  1649.     v3 _ PlanetVectorGlyph new initialize.
  1650.     v3 moveTo: 375 @ 50.
  1651.     v4 _ PlanetVectorGlyph new initialize.
  1652.     v4 moveTo: 450 @ 50.
  1653.     self addGlyph: v1; addGlyph: v2; addGlyph: v3; addGlyph: v4.
  1654.     h1 _ (HSliderGlyph on: gravity) minVal: 0.0; maxVal: 1000000.0; value: 30.0; moveTo: 250 @ 50. 
  1655.     self addGlyph: h1.
  1656.     Transcript cr; show: '..adding stay constraints'.
  1657.     StayConstraint var: v1 p1 xVar strength: #default.
  1658.     StayConstraint var: v1 p1 yVar strength: #default.
  1659.     StayConstraint var: v2 p1 xVar strength: #default.
  1660.     StayConstraint var: v2 p1 yVar strength: #default.
  1661.     StayConstraint var: v3 p1 xVar strength: #default.
  1662.     StayConstraint var: v3 p1 yVar strength: #default.
  1663.     StayConstraint var: v4 p1 xVar strength: #default.
  1664.     StayConstraint var: v4 p1 yVar strength: #default.
  1665.     Transcript cr; show: '..adding interface constraints'.
  1666.     c _ Constraint names: #(v prev deltav ) methods: #('v _ prev + (deltav // 5)' 'deltav _ (v - prev) * 5' ).
  1667.     c copy
  1668.         var: v1 arrowHead vector xVar
  1669.         var: v1 arrowHead vector xVar last
  1670.         var: v2 arrowHead vector xVar
  1671.         strength: #required.
  1672.     c copy
  1673.         var: v1 arrowHead vector yVar
  1674.         var: v1 arrowHead vector yVar last
  1675.         var: v2 arrowHead vector yVar
  1676.         strength: #required.
  1677.     c copy
  1678.         var: v4 arrowHead vector xVar
  1679.         var: v4 arrowHead vector xVar last
  1680.         var: v3 arrowHead vector xVar
  1681.         strength: #required.
  1682.     c copy
  1683.         var: v4 arrowHead vector yVar
  1684.         var: v4 arrowHead vector yVar last
  1685.         var: v3 arrowHead vector yVar
  1686.         strength: #required.
  1687.     Transcript cr; show: '..adding behavior constraints'.
  1688.     c _ Constraint names: #(v prev deltav ) methods: #(
  1689.         'v _ ((prev + (deltav // 5)) < 0
  1690.             ifTrue: [0]
  1691.             ifFalse: [(prev + (deltav // 5)) > 500
  1692.                 ifTrue: [500]
  1693.                 ifFalse: [prev + (deltav // 5)]])' 'deltav _ (v - prev) * 5' ).
  1694.     c copy
  1695.         var: planet1 xVar
  1696.         var: planet1 xVar last
  1697.         var: v1 arrowHead vector xVar
  1698.         strength: #required.
  1699.     c copy
  1700.         var: planet1 yVar
  1701.         var: planet1 yVar last
  1702.         var: v1 arrowHead vector yVar
  1703.         strength: #required.
  1704.     c copy
  1705.         var: planet2 xVar
  1706.         var: planet2 xVar last
  1707.         var: v4 arrowHead vector xVar
  1708.         strength: #required.
  1709.     c copy
  1710.         var: planet2 yVar
  1711.         var: planet2 yVar last
  1712.         var: v4 arrowHead vector yVar
  1713.         strength: #required.
  1714.     cx _ Constraint names: #(p1x p1y p2x p2y ax g) methods: #(
  1715.         'ax _ (g * (
  1716.             (p2x - p1x) abs < 1
  1717.                 ifTrue: [0]
  1718.                 ifFalse: [((p2x - p1x) / ((p2x - p1x) squared + (p2y - p1y) squared) sqrt)
  1719.                         / ((p2x - p1x) squared + (p2y - p1y) squared)]))').
  1720.     cy _ Constraint names: #(p1x p1y p2x p2y ay g) methods: #(
  1721.         'ay _ (g * (
  1722.             (p2y - p1y) abs < 1
  1723.                 ifTrue: [0]
  1724.                 ifFalse: [((p2y - p1y) / ((p2x - p1x) squared + (p2y - p1y) squared) sqrt)
  1725.                         / ((p2x - p1x) squared + (p2y - p1y) squared)]))').
  1726.     cx copy
  1727.         var: planet1 xVar last
  1728.         var: planet1 yVar last
  1729.         var: planet2 xVar last
  1730.         var: planet2 yVar last
  1731.         var: v2 arrowHead vector xVar
  1732.         var: gravity
  1733.         strength: #strongDefault.
  1734.     cy copy
  1735.         var: planet1 xVar last
  1736.         var: planet1 yVar last
  1737.         var: planet2 xVar last
  1738.         var: planet2 yVar last
  1739.         var: v2 arrowHead vector yVar
  1740.         var: gravity
  1741.         strength: #strongDefault.
  1742.     cx copy
  1743.         var: planet2 xVar last
  1744.         var: planet2 yVar last
  1745.         var: planet1 xVar last
  1746.         var: planet1 yVar last
  1747.         var: v3 arrowHead vector xVar
  1748.         var: gravity
  1749.         strength: #strongDefault.
  1750.     cy copy
  1751.         var: planet2 xVar last
  1752.         var: planet2 yVar last
  1753.         var: planet1 xVar last
  1754.         var: planet1 yVar last
  1755.         var: v3 arrowHead vector yVar
  1756.         var: gravity
  1757.         strength: #strongDefault.
  1758.     Transcript cr; show: 'finished'!
  1759.  
  1760. initialize
  1761.     super initialize.
  1762.     self create! !
  1763.  
  1764. !TwoPlanetDemo methodsFor: 'public'!
  1765.  
  1766. open
  1767.     "TwoPlanetDemo new open"
  1768.  
  1769.     | topView |
  1770.     topView _ SpecialSystemView
  1771.                 model: nil
  1772.                 label: 'Planet Demo (Real Gravity)'
  1773.                 minimumSize: 525 @ 425.
  1774.     topView borderWidth: 1; addSubView: (SceneView new initialize model: self).
  1775.     topView controller open! !
  1776.  
  1777. !TwoPlanetDemo methodsFor: 'testing'!
  1778.  
  1779. isAnimated
  1780.     ^true! !
  1781.  
  1782. !TwoPlanetDemo methodsFor: 'background processing'!
  1783.  
  1784. computeBackgroundPlan
  1785.     ^Planner extractPlanFromVariables: (Array with: gravity)! !
  1786.  
  1787. LineGlyph subclass: #PlanetVectorGlyph
  1788.     instanceVariableNames: 'arrowHead '
  1789.     classVariableNames: 'ArrowC '
  1790.     poolDictionaries: ''
  1791.     category: 'Minstrel-SIGGRAPH'!
  1792.  
  1793.  
  1794. !PlanetVectorGlyph methodsFor: 'initialize-release'!
  1795.  
  1796. addConstraints
  1797.     | ArrowC |
  1798.     ArrowC isNil ifTrue: [ArrowC _ Constraint names: #(vector p1 p2 ) methods: #('vector _ p2 - p1' 'p2 _ p1 + vector' )].
  1799.     p2 xVar requireEquals: arrowHead location xVar.
  1800.     p2 yVar requireEquals: arrowHead location yVar.
  1801.     ArrowC copy
  1802.         var: arrowHead vector xVar
  1803.         var: p1 xVar
  1804.         var: p2 xVar
  1805.         strength: #required.
  1806.     ArrowC copy
  1807.         var: arrowHead vector yVar
  1808.         var: p1 yVar
  1809.         var: p2 yVar
  1810.         strength: #required!
  1811.  
  1812. initialize
  1813.     "p1 is the base of the vector, a PointGlyph.
  1814.      p2 is the head of the vector, an InvisiblePointGlyph"
  1815.  
  1816.     super initialize.
  1817.     p1 _ PointGlyph new moveTo: 10@10.
  1818.     p2 _ InvisiblePointGlyph new moveTo: 30@30.
  1819.     arrowHead _ ArrowHeadGlyph new.
  1820.     self addConstraints.! !
  1821.  
  1822. !PlanetVectorGlyph methodsFor: 'accessing'!
  1823.  
  1824. arrowHead
  1825.     ^arrowHead! !
  1826. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  1827.  
  1828. PlanetVectorGlyph class
  1829.     instanceVariableNames: ''!
  1830.  
  1831.  
  1832. !PlanetVectorGlyph class methodsFor: 'constraint release'!
  1833.  
  1834. releaseConstraints
  1835.     "PlanetVectorGlyph releaseConstraints"
  1836.  
  1837.     ArrowC _ nil! !
  1838.  
  1839. !PlanetVectorGlyph class methodsFor: 'classification'!
  1840.  
  1841. glyphCategory
  1842.     ^'SIGGRAPH'! !
  1843.  
  1844.  
  1845. !VectorGlyph class methodsFor: 'constraint release'!
  1846.  
  1847. releaseConstraints
  1848.     "VectorGlyph releaseConstraints"
  1849.  
  1850.     ArrowC _ nil.
  1851.     DirectionC _ nil.! !
  1852.  
  1853. Scene subclass: #MacDrawDemo
  1854.     instanceVariableNames: 'dashes draggers sparedragger selfvariable '
  1855.     classVariableNames: 'CalculateSpareConstraint DashDragAlignConstraint MaxLengthConstraint MinLengthConstraint MinRight2Constraint MinRightConstraint '
  1856.     poolDictionaries: ''
  1857.     category: 'Minstrel-SIGGRAPH'!
  1858. MacDrawDemo comment:
  1859. '                            ***** Complex Graphical User Interfaces (MacDraw II) *****
  1860.  
  1861. This demo was taken from the MacDraw II Dashed Lines dialog box, a user interface widget for defining the number and length of the black and white dashes that, together, comprise a dashed line.  In the original MacDraw II, this dialog box was implemented completely in Pascal: the programmer designed the box, extracted the constraints, hand-solved them, coded them in Pascal, and debugged and debugged and debugged.  In this version, the behavior is almost completely defined by constraints.  Even the existence or non-existence of the dashes is defined by constraints.
  1862.  
  1863. This dialog box uses three basic types of constraints: data consistency constraints, graphical constraints, and behavioral constraints.  Data consistency constraints include: no dash shall be shorted than 5 pixels.  No dash shall be longer than 125 pixels.  There must be at least two dashes.  There can be no more than six dashes.  Etc.  Graphical constraints include keeping the "draggers" aligned with the right end of their respective dash expect for the last one which can be dragged to the far right edge to delete a dash.  Behavioral constraints are basically internal but include such things as the existence of dashes and draggers, and "snapping" action which occurs when the last dragger is released between the right end of its dash and the right edge of the box.
  1864.  
  1865. Interesting actions to try include: (1) trying to shrink a dash too far, (2) trying to grow a dash too large, (3) dragging the last dragger to the far right, (4) dragging the dragger on the far right (if there you left it there) off the far right "parking" place, (5) trying to compact a dash on the right by shoving it against the edge with a dash from the middle, and (6) releasing the last dragger half-way between the end of its dash and the right edge of the box.
  1866. '!
  1867.  
  1868.  
  1869. !MacDrawDemo methodsFor: 'initialize-release'!
  1870.  
  1871. create1
  1872.     | c d |
  1873.     Transcript cr; show: 'Building the ' , self class name , '..'.
  1874.     Transcript cr; show: '..adding the dashes'.
  1875.     dashes _ d _ Array new: 6.
  1876.     1 to: d size do: [:i | d at: i put: (MacDrawDashGlyph new initialize: i)].
  1877.     (d at: 1) left0 value: MacDrawDemo leftEdge.
  1878.     2 to: d size + 1 do: 
  1879.         [:i | 
  1880.         (d at: i - 1) right0 value: (d at: i - 1) left0 value + (d at: i - 1) length0 value.
  1881.         (d at: i - 1) right1 value: (d at: i - 1) left1 value + (d at: i - 1) length1 value.
  1882.         (d at: i - 1) right2 value: (d at: i - 1) left2 value + (d at: i - 1) length2 value.
  1883.         (d at: i - 1) right3 value: (d at: i - 1) left3 value + (d at: i - 1) length3 value.
  1884.         (d at: i - 1) color value: i even.
  1885.         i > d size
  1886.             ifFalse: 
  1887.                 [(d at: i) left0 value: (d at: i - 1) right0 value.
  1888.                 (d at: i) left1 value: (d at: i - 1) right1 value.
  1889.                 (d at: i) left2 value: (d at: i - 1) right2 value.
  1890.                 (d at: i) left3 value: (d at: i - 1) right3 value]].
  1891.     1 to: d size do: [:i | self addGlyph: (d at: i)].
  1892.     Transcript cr; show: '..adding the dash constraints'.
  1893.     (StayConstraint var: (d at: 1) left0 strength: #required) name: 'initial length0 stay'.
  1894.     (StayConstraint var: (d at: 1) left1 strength: #required) name: 'initial length1 stay'.
  1895.     (StayConstraint var: (d at: 1) left2 strength: #required) name: 'initial length2 stay'.
  1896.     (StayConstraint var: (d at: 1) left3 strength: #required) name: 'initial length3 stay'.
  1897.     2 to: d size do: 
  1898.         [:i | 
  1899.         (EqualityConstraint
  1900.             var: (d at: i - 1) right0
  1901.             var: (d at: i) left0
  1902.             strength: #required) name: ((i-1) printString), ':right0 = ', (i printString), ':left0'.
  1903.         (EqualityConstraint
  1904.             var: (d at: i - 1) right1
  1905.             var: (d at: i) left1
  1906.             strength: #required) name: ((i-1) printString), ':right1 = ', (i printString), ':left1'.
  1907.         (EqualityConstraint
  1908.             var: (d at: i - 1) right2
  1909.             var: (d at: i) left2
  1910.             strength: #required) name: ((i-1) printString), ':right2 = ', (i printString), ':left2'.
  1911.         (EqualityConstraint
  1912.             var: (d at: i - 1) right3
  1913.             var: (d at: i) left3
  1914.             strength: #required) name: ((i-1) printString), ':right3 = ', (i printString), ':left3'].
  1915.     (StayConstraint var: (d at: 1) color strength: #required) name: 'initial color stay'.
  1916.     c _ Constraint names: #(left right ) methods: #('left _ right not' 'right _ left not' ).
  1917.     2 to: d size do: [:i | (c copy
  1918.             var: (d at: i - 1) color
  1919.             var: (d at: i) color
  1920.             strength: #required) name: (i printString), ':color alternate'].
  1921.     self create2!
  1922.  
  1923. create2
  1924.     | d |
  1925.     Transcript cr; show: '..adding the draggers'.
  1926.     d _ draggers _ Array new: dashes size.
  1927.     1 to: d size do: [:i | d at: i put: (MacDrawDraggerGlyph new initialize: i)].
  1928.     d with: dashes do: [:drag :dash | drag dash: dash scene: self].
  1929.     d do: [:each | self addGlyph: each].
  1930.     (d at: 1) height value: 20 + MacDrawDemo dragTop.
  1931.     Transcript cr; show: '..adding the dragger constraints'.
  1932.     (StayConstraint var: (d at: 1) height strength: #required) name: 'initial height'.
  1933.     2 to: d size do: [:i | (OffsetConstraint
  1934.             from: (d at: i - 1) height
  1935.             to: (d at: i) height
  1936.             strength: #required
  1937.             offset: MacDrawDemo dragBox height) name: i printString, ':height descent'].
  1938.     1 to: d size do: [:i |
  1939.             drag _ d at: i.
  1940.             dash _ dashes at: i.
  1941.             self defaultFlexiForDash: dash andDragger: drag atIndex: i].
  1942.     self create3!
  1943.  
  1944. create3
  1945.     | c |
  1946.     Transcript cr; show: '..adding the ruler'.
  1947.     self addGlyph: MacDrawRulerGlyph new.
  1948.     sparedragger _ FreeVariable value: 0.
  1949.     selfvariable _ FreeVariable value: self.
  1950.     Transcript cr; show: '..adding the existence constraints'.
  1951.     c _ Constraint names: #(exists offset ) methods: #('exists _ (offset = MacDrawDemo rightEdge) not' ).
  1952.     1 to: dashes size do: [:i | (c copy
  1953.             var: (dashes at: i) exists
  1954.             var: (draggers at: i) offset
  1955.             strength: #required)
  1956.             name: i printString , ':dash exists _ dragger atRight'].
  1957.     3 to: dashes size do: [:i | ((Constraint names: #(exists dashexists spare ) methods: (Array with: 'exists _ dashexists | (spare = ', i printString, ')'))
  1958.             var: (draggers at: i) exists
  1959.             var: (dashes at: i) exists
  1960.             var: sparedragger
  1961.             strength: #required)
  1962.             name: i printString , ':dragger exists _ dash exists or spare=', i printString].
  1963.     Transcript cr; show: '..initializing'.
  1964.     self cleanUpFor: nil and: nil.
  1965.     Transcript cr; show: 'finished'!
  1966.  
  1967. defaultFlexiForDash: aDash andDragger: aDragger atIndex: i 
  1968.     aDragger doDashDraggerAlignDefault: i!
  1969.  
  1970. initialize
  1971.     super initialize.
  1972.     self create1! !
  1973.  
  1974. !MacDrawDemo methodsFor: 'public'!
  1975.  
  1976. open
  1977.     "MacDrawDemo new open"
  1978.  
  1979.     | topView |
  1980.     topView _ SpecialSystemView
  1981.                 model: nil
  1982.                 label: 'MacDraw II Dialog Box'
  1983.                 minimumSize: 600 @ 400.
  1984.     topView borderWidth: 1; addSubView: (MacDrawDemoView new initialize model: self).
  1985.     topView controller open! !
  1986.  
  1987. !MacDrawDemo methodsFor: 'access'!
  1988.  
  1989. lastdash
  1990.     | l |
  1991.     l _ dashes inject: nil into: [:last :dash | dash exists value
  1992.                     ifTrue: [dash]
  1993.                     ifFalse: [last]].
  1994.     "l == dashes last ifFalse: [Transcript cr; show: 'Notice: lastdash ~~ dashes last']."
  1995.     ^l!
  1996.  
  1997. seconddash
  1998.     ^dashes at: 2! !
  1999.  
  2000. !MacDrawDemo methodsFor: 'direct manipulation'!
  2001.  
  2002. cleanUpFor: aDragger and: aDash 
  2003.     | i |
  2004.     aDragger notNil
  2005.         ifTrue: 
  2006.             [i _ dashes indexOf: aDash.
  2007.             self defaultFlexiForDash: aDash andDragger: aDragger atIndex: i].
  2008.     dashes do: 
  2009.         [:each | 
  2010.         each right1 value: each right0 value.
  2011.         each right2 value: each right1 value.
  2012.         each right3 value: each right2 value.
  2013.         each length1 value: each length0 value.
  2014.         each length2 value: each length1 value.
  2015.         each length3 value: each length2 value.
  2016.         each left1 value: each left0 value.
  2017.         each left2 value: each left1 value.
  2018.         each left3 value: each left2 value]!
  2019.  
  2020. computeSpare: ignore
  2021.     | i |
  2022.     i _ dashes indexOf: self lastdash.
  2023.     ^i = dashes size
  2024.                 ifTrue: [0]
  2025.                 ifFalse: [i + 1]!
  2026.  
  2027. editConstraints1For: aDragger and: aDash at: idx into: cons
  2028.     "== == == == == == == == == == == == == == == == == == == == == == == == 
  2029.                             mouse
  2030.                                 |
  2031.                                 v
  2032.     dash3        dash3        dash3*        dash3        dash3"
  2033.     cons addFirst: ((XMouseConstraint
  2034.             var: aDash right3
  2035.             strength: #required
  2036.             offset: aDragger offset value - Sensor mousePoint x) name: 'on ', idx printString).!
  2037.  
  2038. editConstraints2For: aDragger and: aDash at: idx into: cons
  2039.     "== == == == == == == == == == == == == == == == == == == == == == == == 
  2040.                             dragger
  2041.                                 ^
  2042.                                 |
  2043.     dash1        dash1        dash1*        dash1        dash1"
  2044.     ((aDash == self lastdash | aDragger isSpare) and: [(aDash == self seconddash) not])
  2045.         ifTrue: [aDragger doDashDraggerAlignMovement: idx].!
  2046.  
  2047. editConstraints3For: aDragger and: aDash at: idx into: cons
  2048.     "== == == == == == == == == == == == == == == == == == == == == == == == 
  2049.                             spare
  2050.                                 ^
  2051.                                 |
  2052.     dash0        dash0        dash0*        dash0        dash0"
  2053.     CalculateSpareConstraint isNil ifTrue: [CalculateSpareConstraint _ (Constraint
  2054.         names: #(spare scene offset)
  2055.         methods: #('spare _ scene computeSpare: offset'))
  2056.         name: 'spare computation' ].
  2057.     cons add: (CalculateSpareConstraint copy
  2058.                 var: sparedragger
  2059.                 var: selfvariable
  2060.                 var: aDash exists
  2061.                 strength: #required).!
  2062.  
  2063. editConstraints4For: aDragger and: aDash at: idx into: cons
  2064.     | each |
  2065.     "== == == == == == == == == == == == == == == == == == == == == == == == 
  2066.     dash3        dash3        dash3*        dash3        dash3
  2067.     stay        stay                    stay        stay
  2068.  
  2069.     dash2        dash2        dash2*        dash2        dash2
  2070.     stay        stay                    stay        stay
  2071.  
  2072.     dash1        dash1        dash1*        dash1        dash1
  2073.     stay        stay                    stay        stay
  2074.  
  2075.     dash0        dash0        dash0*        dash0        dash0
  2076.     stay        stay                    stay        stay"
  2077.     1 to: dashes size do: [:i | each _ dashes at: i.
  2078.         each == aDash
  2079.             ifFalse: 
  2080.                 [cons add: ((StayConstraint var: each length3 strength: #required) name: i printString, ':length3 stay').
  2081.                 cons add: ((StayConstraint var: each length2 strength: #required) name: i printString, ':length2 stay').
  2082.                 cons add: ((StayConstraint var: each length1 strength: #required) name: i printString, ':length1 stay').
  2083.                 cons add: ((StayConstraint var: each length0 strength: #required) name: i printString, ':length0 stay').]].!
  2084.  
  2085. editConstraints5For: aDragger and: aDash at: idx into: cons
  2086.     "== == == == == == == == == == == == == == == == == == == == == == == == 
  2087.     dash3        dash3        dash3*        dash3        dash3
  2088.                                 | minimum length
  2089.                                 v
  2090.     dash2        dash2        dash2*        dash2        dash2"
  2091.     MinLengthConstraint isNil ifTrue: [MinLengthConstraint _ Constraint
  2092.         names: #(v pv )
  2093.         methods: #('v _ pv max: MacDrawDemo minDash' )].
  2094.     cons add: ((MinLengthConstraint copy
  2095.             var: aDash length2
  2096.             var: aDash length3
  2097.             strength: #required) name: idx printString, ': length2 = min length3').!
  2098.  
  2099. editConstraints6For: aDragger and: aDash at: idx into: cons
  2100.     "== == == == == == == == == == == == == == == == == == == == == == == == 
  2101.     dash1        dash1        dash1*        dash1        dash1
  2102.                                 | maximum length
  2103.                                 v
  2104.     dash0        dash0        dash0*        dash0        dash0"
  2105.     MaxLengthConstraint isNil ifTrue: [MaxLengthConstraint _ Constraint
  2106.         names: #(v pv )
  2107.         methods: #('v _ pv min: MacDrawDemo maxDash' )].
  2108.     cons add: ((MaxLengthConstraint copy
  2109.             var: aDash length0
  2110.             var: aDash length1
  2111.             strength: #required) name: idx printString, ': length0 = min max length1').!
  2112.  
  2113. editConstraints7For: aDragger and: aDash at: idx into: cons
  2114.     "== == == == == == == == == == == == == == == == == == == == == == == == 
  2115.     dash2        dash2        dash2*        dash2        dash2
  2116.                                                         | not beyond right edge
  2117.                                                         v
  2118.     dash1        dash1        dash1*        dash1        dash1"
  2119.     MinRightConstraint isNil ifTrue: [MinRightConstraint _ Constraint
  2120.         names: #(v pv )
  2121.         methods: #('v _ pv min: MacDrawDemo rightEdge' )].
  2122.     MinRight2Constraint isNil ifTrue: [MinRight2Constraint _ Constraint
  2123.         names: #(v pv )
  2124.         methods: #('v _ pv min: MacDrawDemo rightEdge - 1' )].
  2125.     aDragger isSpare
  2126.         ifTrue: [cons add: ((MinRightConstraint copy
  2127.                     var: aDragger dash right1
  2128.                     var: aDragger dash right2
  2129.                     strength: #required) name: idx printString, ': right1 = min right2')]
  2130.         ifFalse:[aDash == self lastdash
  2131.                     ifTrue: [cons add: ((MinRightConstraint copy
  2132.                             var: self lastdash right1
  2133.                             var: self lastdash right2
  2134.                             strength: #required)
  2135.                             name: idx printString, ': right1 = min right2')]
  2136.                     ifFalse: [cons add: ((MinRight2Constraint copy
  2137.                             var: self lastdash right1
  2138.                             var: self lastdash right2
  2139.                             strength: #required)
  2140.                             name: idx printString, ': right1 = min-1 right2')]].!
  2141.  
  2142. editConstraintsFor: aDragger and: aDash 
  2143.     | cons idx |
  2144.     cons _ OrderedCollection new.
  2145.     idx _ dashes indexOf: aDash.
  2146.     self editDebugFor: aDragger and: aDash mark: 0.
  2147.     self editConstraints1For: aDragger and: aDash at: idx into: cons.
  2148.     self editDebugFor: aDragger and: aDash mark: 1.
  2149.     self editConstraints2For: aDragger and: aDash at: idx into: cons.
  2150.     self editDebugFor: aDragger and: aDash mark: 2.
  2151.     self editConstraints3For: aDragger and: aDash at: idx into: cons.
  2152.     self editDebugFor: aDragger and: aDash mark: 3.
  2153.     self editConstraints4For: aDragger and: aDash at: idx into: cons.
  2154.     self editDebugFor: aDragger and: aDash mark: 4.
  2155.     self editConstraints5For: aDragger and: aDash at: idx into: cons.
  2156.     self editDebugFor: aDragger and: aDash mark: 5.
  2157.     self editConstraints6For: aDragger and: aDash at: idx into: cons.
  2158.     self editDebugFor: aDragger and: aDash mark: 6.
  2159.     self editConstraints7For: aDragger and: aDash at: idx into: cons.
  2160.     self editDebugFor: aDragger and: aDash mark: 7.
  2161.     ^cons!
  2162.  
  2163. editDebugFor: aDragger and: aDash mark: aMark
  2164.     | collec st s0 s1 s2 s3 d | 
  2165. true ifTrue: [^self].
  2166. collec _ Array
  2167.     with: (Array with: 5 with: (dashes at: 5))
  2168.     with: (Array with: 6 with: (dashes at: 6)).
  2169. st _ String new writeStream. st nextPut: $[. aMark printOn: st. st nextPut: $].
  2170. s0 _ String new writeStream. s0 nextPutAll: '0:'.
  2171. s1 _ String new writeStream. s1 nextPutAll: '1:'.
  2172. s2 _ String new writeStream. s2 nextPutAll: '2:'.
  2173. s3 _ String new writeStream. s3 nextPutAll: '3:'.
  2174. collec do: [:each |
  2175. d _ (each at: 2).
  2176. st tab; tab. (each at: 1) printOn: st. st tab; tab.
  2177. s3 tab. d left3 value printOn: s3. s3 tab.
  2178. d length3 value printOn: s3. s3 tab.
  2179. d right3 value printOn: s3. s3 tab.
  2180. s2 tab. d left2 value printOn: s2. s2 tab.
  2181. d length2 value printOn: s2. s2 tab.
  2182. d right2 value printOn: s2. s2 tab.
  2183. s1 tab. d left1 value printOn: s1. s1 tab.
  2184. d length1 value printOn: s1. s1 tab.
  2185. d right1 value printOn: s1. s1 tab.
  2186. s0 tab. d left0 value printOn: s0. s0 tab.
  2187. d length0 value printOn: s0. s0 tab.
  2188. d right0 value printOn: s0. s0 tab].
  2189. aMark = 0 ifTrue: [Transcript nextPutAll: '--------------------------'; cr].
  2190. Transcript nextPutAll: st contents; cr.
  2191. Transcript nextPutAll: s3 contents; cr; nextPutAll: s2 contents; cr.
  2192. Transcript nextPutAll: s1 contents; cr; nextPutAll: s0 contents; cr.
  2193. Transcript show: ''! !
  2194. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  2195.  
  2196. MacDrawDemo class
  2197.     instanceVariableNames: 'draggerBoxForm '!
  2198.  
  2199.  
  2200. !MacDrawDemo class methodsFor: 'class initialization'!
  2201.  
  2202. initialize
  2203.     "MacDrawDemo initialize."
  2204.  
  2205.     draggerBoxForm _ Form extent: self dragBox extent.
  2206.     draggerBoxForm white.
  2207.     draggerBoxForm border: draggerBoxForm boundingBox width: 1.
  2208.     draggerBoxForm offset: (MacDrawDemo dragBox width // -2 @ (MacDrawDemo dragBox height // -2)).! !
  2209.  
  2210. !MacDrawDemo class methodsFor: 'layout constants'!
  2211.  
  2212. dashBottom
  2213.     ^self dashTop + 20!
  2214.  
  2215. dashTop
  2216.     ^250!
  2217.  
  2218. dragBottom
  2219.     ^self dashTop - 20!
  2220.  
  2221. dragBox
  2222.     ^0@0 extent: 10@10!
  2223.  
  2224. draggerBoxForm
  2225.     ^draggerBoxForm!
  2226.  
  2227. dragTop
  2228.     ^self dragBottom - 100!
  2229.  
  2230. leftEdge
  2231.     ^50!
  2232.  
  2233. maxDash
  2234.     ^125!
  2235.  
  2236. minDash
  2237.     ^5!
  2238.  
  2239. rightEdge
  2240.     ^550! !
  2241.  
  2242. !MacDrawDemo class methodsFor: 'constraint release'!
  2243.  
  2244. releaseConstraints
  2245.     "MacDrawDemo releaseConstraints"
  2246.  
  2247.     MinLengthConstraint _ MaxLengthConstraint _ MinRightConstraint _ MinRight2Constraint _ DashDragAlignConstraint _ CalculateSpareConstraint _ nil! !
  2248.  
  2249. !MacDrawDemo class methodsFor: 'access'!
  2250.  
  2251. infoSize
  2252.     ^700@330! !
  2253.  
  2254. MacDrawDemo initialize!
  2255.  
  2256. GestureController subclass: #SceneController
  2257.     instanceVariableNames: 'myMenu lastMenuItem running lastPartsMenuString partsMenuCache thePlan '
  2258.     classVariableNames: ''
  2259.     poolDictionaries: ''
  2260.     category: 'Minstrel-View'!
  2261.  
  2262.  
  2263. !SceneController methodsFor: 'control defaults'!
  2264.  
  2265. controlActivity
  2266.     "Process user mouse and keyboard activity."
  2267.  
  2268.     (sensor keyboardPressed) ifTrue: [^self readKeyboard].
  2269.     (sensor yellowButtonPressed) ifTrue: [^self menuActivity].
  2270.  
  2271.     "The following code allows click, drag, and sweep gestures even in 'operate' mode:"
  2272.     (sensor redButtonPressed) ifTrue: [^self possibleClickAt: sensor cursorPoint].
  2273.  
  2274.     "Note: replace the previous code with the following to disable click, drag, and sweep gestures in 'operate' mode. This is good for naive users and quick response."
  2275.     "(sensor redButtonPressed) ifTrue:
  2276.         [(running)
  2277.             ifTrue: [^self processMouseAt: sensor cursorPoint]
  2278.             ifFalse: [^self possibleClickAt: sensor cursorPoint]]."
  2279.  
  2280.     "model backgroundTask: view."
  2281.     thePlan notNil
  2282.         ifTrue: 
  2283.             [thePlan execute.
  2284.             view displayFeedback]!
  2285.  
  2286. controlInitialize
  2287.     super controlInitialize.
  2288.     model isAnimated
  2289.         ifTrue: [thePlan isNil
  2290.                 ifTrue: 
  2291.                     [thePlan _ model computeBackgroundPlan.
  2292.                     view computeBackground]]
  2293.         ifFalse: [thePlan _ nil]! !
  2294.  
  2295. !SceneController methodsFor: 'direct manipulation'!
  2296.  
  2297. while: testBlock move: pointsToMove refPoint: refPoint mergeWith: mergeGlyph 
  2298.     "Move the given points using mouse constraints. Any glyphs attached to the  
  2299.     points will follow the mouse until testBlock is false. If mergeGlyph is not nil, try  
  2300.     to merge it with the glyph (if any) at its new location."
  2301.  
  2302.     | mergeable mouseConstraints offset views mousePoint oldMousePoint target starterConstraints |
  2303.     mergeGlyph notNil
  2304.         ifTrue: 
  2305.             [mergeable _ OrderedCollection new: 100.
  2306.             model selectableGlyphsDo: [:g | (g includesObjectIn: pointsToMove)
  2307.                     ifFalse: [mergeable add: g]]].
  2308.     mouseConstraints _ OrderedCollection new.
  2309.     pointsToMove do: 
  2310.         [:p | 
  2311.         offset _ p - refPoint.
  2312.         mouseConstraints add: (XMouseConstraint
  2313.                 var: p xVar
  2314.                 strength: #preferred
  2315.                 offset: offset x); add: (YMouseConstraint
  2316.                 var: p yVar
  2317.                 strength: #preferred
  2318.                 offset: offset y)].
  2319.     thePlan notNil ifTrue: [].
  2320.     model isAnimated
  2321.         ifTrue: [starterConstraints _ mouseConstraints , model initialAnimationConstraints]
  2322.         ifFalse: [starterConstraints _ mouseConstraints].
  2323.     thePlan _ Planner extractPlanFromInputConstraints: starterConstraints.
  2324.     "views _ SceneView allInstances select: [: v | v isAlive].  
  2325.     views do: [: v | v computeBackground]."
  2326.     view computeBackground.
  2327.     [testBlock value]
  2328.         whileTrue: 
  2329.             [mousePoint _ sensor cursorPoint.
  2330.             (oldMousePoint ~= sensor cursorPoint or: [model isAnimated])
  2331.                 ifTrue: 
  2332.                     [target _ nil.
  2333.                     mergeGlyph notNil ifTrue: [mergeable do: [:g | ((g containsPoint: mousePoint + offset)
  2334.                                 and: [(g canMergeWith: mergeGlyph)
  2335.                                         or: [mergeGlyph canMergeWith: g]])
  2336.                                 ifTrue: [target _ g]]].
  2337.                     thePlan execute.
  2338.                     "views do:  
  2339.                     [: v |  
  2340.                      ((target notNil) and: [v == view])  
  2341.                     ifTrue:  
  2342.                     [v    displayFeedbackWithBox:  
  2343.                     (target boundingBox expandBy: 6)  
  2344.                     width: 2]  
  2345.                     ifFalse: [v displayFeedback]]]."
  2346.                     target notNil
  2347.                         ifTrue: [view displayFeedbackWithBox: (target boundingBox expandBy: 6)
  2348.                                 width: 2]
  2349.                         ifFalse: [view displayFeedback]].
  2350.             oldMousePoint _ mousePoint].
  2351.     mouseConstraints do: [:c | c destroyConstraint].
  2352.     target notNil ifTrue: [self mergeGlyphs: (OrderedCollection with: target with: mergeGlyph)].
  2353.     view computeEnclosingRectangle.
  2354.     view displayScene.
  2355.     model isAnimated
  2356.         ifTrue: 
  2357.             [thePlan _ model computeBackgroundPlan.
  2358.             view computeBackground]
  2359.         ifFalse: [thePlan _ nil]! !
  2360.  
  2361. !SceneController methodsFor: 'keyboard'!
  2362.  
  2363. readKeyboard
  2364.     "Keystrokes are sent to all selected Things that are interested in keyboard 
  2365.     input. "
  2366.  
  2367.     | selected interested char editVars editConstraints |
  2368.     selected _ model selected.
  2369.     interested _ IdentitySet new: 10.
  2370.     editVars _ IdentitySet new: 10.
  2371.     model inputGlyphsDo: [:g | (g wantsKeystrokes and: [selected includes: g])
  2372.             ifTrue: 
  2373.                 [interested add: g.
  2374.                 editVars addAll: g keystrokeVars]].
  2375.     editConstraints _ editVars collect: [:var | EditConstraint var: var strength: #preferred].
  2376.     thePlan notNil ifTrue: [].
  2377.     thePlan _ Planner extractPlanFromInputConstraints: editConstraints.
  2378.     view computeBackground.
  2379.     [sensor keyboardPressed]
  2380.         whileTrue: 
  2381.             [self resetTimer.
  2382.             char _ sensor keyboard.
  2383.             interested do: [:thing | thing handleKeystroke: char view: view].
  2384.             [(self timeOut: 300)
  2385.                 | sensor keyboardPressed]
  2386.                 whileFalse: ["wait a bit in case there is another character"
  2387.                     ].
  2388.             sensor keyboardPressed
  2389.                 ifFalse: 
  2390.                     [thePlan execute.
  2391.                     view displayFeedback]].
  2392.     editConstraints do: [:c | c destroyConstraint].
  2393.     "SceneView allInstancesDo: 
  2394.     [: v | 
  2395.      (v isAlive) ifTrue: 
  2396.     [v displaySafe: [v displayScene]]]."
  2397.     view isAlive ifTrue: [view displaySafe: [view displayScene]].
  2398.     model isAnimated
  2399.         ifTrue:
  2400.             [thePlan _ model computeBackgroundPlan.
  2401.             view computeBackground]
  2402.         ifFalse: [thePlan _ nil]! !
  2403.  
  2404. Scene subclass: #RaisingDemo
  2405.     instanceVariableNames: 'fakemouse '
  2406.     classVariableNames: ''
  2407.     poolDictionaries: ''
  2408.     category: 'Minstrel-SIGGRAPH'!
  2409.  
  2410.  
  2411. !RaisingDemo methodsFor: 'initialize-release'!
  2412.  
  2413. create
  2414.     | hl vl m c |
  2415.     Transcript cr; show: 'Building the ' , self class name , '..'.
  2416.     Transcript cr; show: '..adding the components'.
  2417.     m _ FakeMouseGlyph new initialize.
  2418.     hl _ LineGlyph new.
  2419.     hl moveTo: 100 @ 100.
  2420.     vl _ LineGlyph new.
  2421.     vl moveTo: 100 @ 150.
  2422.     self addGlyph: m; addGlyph: hl; addGlyph: vl.
  2423.     Transcript cr; show: '..adding the consistency constraints'.
  2424.     EqualityConstraint
  2425.         var: hl p1 yVar
  2426.         var: hl p2 yVar
  2427.         strength: #weakDefault.
  2428.     EqualityConstraint
  2429.         var: vl p1 xVar
  2430.         var: vl p2 xVar
  2431.         strength: #required.
  2432.     (Constraint names: #(y1 y1p y2 y2p)
  2433.         methods: #('y1 _ y1p' 'y2 _ y2p'))
  2434.             var: vl p1 yVar
  2435.             var: vl p1 yVar last
  2436.             var: vl p2 yVar
  2437.             var: vl p2 yVar last
  2438.             strength: #required.
  2439.     EqualityConstraint
  2440.         var: hl p1 yVar
  2441.         var: vl p1 yVar
  2442.         strength: #required.
  2443.     EqualityConstraint
  2444.         var: hl p1 xVar
  2445.         var: vl p1 xVar
  2446.         strength: #required.
  2447.     EqualityConstraint
  2448.         var: vl p2 xVar
  2449.         var: m xVar
  2450.         strength: #required.
  2451.     EqualityConstraint
  2452.         var: vl p2 yVar
  2453.         var: m yVar
  2454.         strength: #required.
  2455.     "c _ Constraint names: #(new old ) methods: #('new _ ((old + SplittingDemo nextRandom) min: 350) max: 5' ).
  2456.     fakemouse _ Array with: (c copy
  2457.                     var: m xVar
  2458.                     var: m xVar last
  2459.                     strength: #default)
  2460.                 with: (c copy
  2461.                         var: m yVar
  2462.                         var: m yVar last
  2463.                         strength: #default)."
  2464.     fakemouse _ Array new: 2.
  2465.     fakemouse at: 1 put: ((Constraint
  2466.         names: #(new old )
  2467.         methods: #('new _ SplittingDemo nextRandomX' ))
  2468.             var: m xVar
  2469.             var: m xVar last
  2470.             strength: #default).
  2471.     fakemouse at: 2 put: ((Constraint
  2472.         names: #(new old )
  2473.         methods: #('new _ SplittingDemo nextRandomY' ))
  2474.             var: m yVar
  2475.             var: m yVar last
  2476.             strength: #default).
  2477.     Transcript cr; show: 'finished'!
  2478.  
  2479. initialize
  2480.     super initialize.
  2481.     self create! !
  2482.  
  2483. !RaisingDemo methodsFor: 'public'!
  2484.  
  2485. open
  2486.     "RaisingDemo new open"
  2487.  
  2488.     | topView |
  2489.     topView _ SpecialSystemView
  2490.                 model: nil
  2491.                 label: 'Raising'
  2492.                 minimumSize: 400 @ 400.
  2493.     topView borderWidth: 1; addSubView: (SceneView new initialize model: self).
  2494.     topView controller open! !
  2495.  
  2496. !RaisingDemo methodsFor: 'testing'!
  2497.  
  2498. isAnimated
  2499.     ^true! !
  2500.  
  2501. !RaisingDemo methodsFor: 'background processing'!
  2502.  
  2503. computeBackgroundPlan
  2504.     ^Planner extractPlanFromInputConstraints: fakemouse!
  2505.  
  2506. initialAnimationConstraints
  2507.     ^fakemouse! !
  2508.  
  2509. Glyph subclass: #MacDrawDashGlyph
  2510.     instanceVariableNames: 'left0 left1 left2 left3 length0 length1 length2 length3 right0 right1 right2 right3 color exists '
  2511.     classVariableNames: 'LengthConstraint '
  2512.     poolDictionaries: ''
  2513.     category: 'Minstrel-SIGGRAPH'!
  2514.  
  2515.  
  2516. !MacDrawDashGlyph methodsFor: 'initialize-release'!
  2517.  
  2518. initialize
  2519.     self initialize: '?'!
  2520.  
  2521. initialize: i 
  2522.     "MacDrawDashGlyph releaseConstraints"
  2523.  
  2524.     super initialize.
  2525.     left0 _ FreeVariable value: 10.
  2526.     left1 _ FreeVariable value: 10.
  2527.     left2 _ FreeVariable value: 10.
  2528.     left3 _ FreeVariable value: 10.
  2529.     right0 _ FreeVariable value: 50.
  2530.     right1 _ FreeVariable value: 50.
  2531.     right2 _ FreeVariable value: 50.
  2532.     right3 _ FreeVariable value: 50.
  2533.     length0 _ FreeVariable value: 40.
  2534.     length1 _ FreeVariable value: 40.
  2535.     length2 _ FreeVariable value: 40.
  2536.     length3 _ FreeVariable value: 40.
  2537.     color _ FreeVariable value: true.
  2538.     exists _ FreeVariable value: true.
  2539.     LengthConstraint isNil ifTrue: [LengthConstraint _ Constraint names: #(left length right ) methods: #('right _ left + length' 'length _ right - left' 'left _ right - length' )].
  2540.     (LengthConstraint copy
  2541.         var: left3
  2542.         var: length3
  2543.         var: right3
  2544.         strength: #required)
  2545.         name: i printString , ':dash length3 = left3 - right3'.
  2546.     (LengthConstraint copy
  2547.         var: left2
  2548.         var: length2
  2549.         var: right2
  2550.         strength: #required)
  2551.         name: i printString , ':dash length2 = left2 - right2'.
  2552.     (LengthConstraint copy
  2553.         var: left1
  2554.         var: length1
  2555.         var: right1
  2556.         strength: #required)
  2557.         name: i printString , ':dash length1 = left1 - right1'.
  2558.     (LengthConstraint copy
  2559.         var: left0
  2560.         var: length0
  2561.         var: right0
  2562.         strength: #required)
  2563.         name: i printString , ':dash length0 = left0 - right0'! !
  2564.  
  2565. !MacDrawDashGlyph methodsFor: 'accessing'!
  2566.  
  2567. color
  2568.     ^color!
  2569.  
  2570. exists
  2571.     ^exists!
  2572.  
  2573. left
  2574.     ^self halt: 'use a different left'!
  2575.  
  2576. left0 ^left0!
  2577.  
  2578. left1 ^left1!
  2579.  
  2580. left2 ^left2!
  2581.  
  2582. left3 ^left3!
  2583.  
  2584. length
  2585.     ^self halt: 'use different length'!
  2586.  
  2587. length0 ^length0!
  2588.  
  2589. length1 ^length1!
  2590.  
  2591. length2 ^length2!
  2592.  
  2593. length3 ^length3!
  2594.  
  2595. right
  2596.     ^self halt: 'use different right'!
  2597.  
  2598. right0 ^right0!
  2599.  
  2600. right1 ^right1!
  2601.  
  2602. right2 ^right2!
  2603.  
  2604. right3 ^right3! !
  2605.  
  2606. !MacDrawDashGlyph methodsFor: 'glyph protocol'!
  2607.  
  2608. displayOn: aDisplayMedium at: aDisplayPoint clip: clipBox 
  2609.     | box |
  2610.     exists value
  2611.         ifTrue: 
  2612.             [box _ left0 value @ MacDrawDemo dashTop corner: right0 value @ MacDrawDemo dashBottom.
  2613.             box translateBy: aDisplayPoint.
  2614.             color value
  2615.                 ifTrue: [aDisplayMedium fill: box mask: Form black]
  2616.                 ifFalse: 
  2617.                     ["aDisplayMedium border: box width: 1."
  2618.                     self
  2619.                         hLineFrom: left0 value rounded @ MacDrawDemo dashTop
  2620.                         length: length0 value rounded
  2621.                         on: aDisplayMedium
  2622.                         at: aDisplayPoint
  2623.                         clip: clipBox.
  2624.                     self
  2625.                         hLineFrom: left0 value rounded @ (MacDrawDemo dashBottom - 1)
  2626.                         length: length0 value rounded
  2627.                         on: aDisplayMedium
  2628.                         at: aDisplayPoint
  2629.                         clip: clipBox]]!
  2630.  
  2631. locationPoints
  2632.     ^Array with: left0 value + right0 value // 2 @ (MacDrawDemo dashTop + MacDrawDemo dashBottom // 2)! !
  2633. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  2634.  
  2635. MacDrawDashGlyph class
  2636.     instanceVariableNames: ''!
  2637.  
  2638.  
  2639. !MacDrawDashGlyph class methodsFor: 'classification'!
  2640.  
  2641. glyphCategory
  2642.     ^'SIGGRAPH'! !
  2643.  
  2644. !MacDrawDashGlyph class methodsFor: 'constraint release'!
  2645.  
  2646. releaseConstraints
  2647.     "MacDrawDashGlyph releaseConstraints"
  2648.  
  2649.     LengthConstraint _ nil! !
  2650.  
  2651. Scene subclass: #SplittingDemo
  2652.     instanceVariableNames: 'fakemouse '
  2653.     classVariableNames: 'RandomStream '
  2654.     poolDictionaries: ''
  2655.     category: 'Minstrel-SIGGRAPH'!
  2656. SplittingDemo comment:
  2657. '                            ***** Constraint on Objects (Multi-User Application) *****
  2658.  
  2659. These demos illustrate two features of constraint systems: (one) constraints can be useful in the development of today''s multi-user, multi-media, multi-buzzword applications, and (two) constraints on complex objects can be implemented in a number of ways.  These demos illustrate two mechanisms: splitting (decomposing a constraint on a whole object into separate constraints on each of its parts) and raising (moving constraints on an object''s parts "up" to become constraints on the whole object).  Numerous other mechanisms also exist.
  2660.  
  2661. In these examples, we assume a two-user, two-mouse interactive graphical editor.  Here, however, the second user is simulated by the computer.  Note that even while the second user is busy editting her objects, the first user (you) can still edit yours.  Again, this is because all interactions are implemented with constraints and the system can solve many constraints just as easily as it can solve a few.
  2662.  
  2663. Each of these demos has a horizontal line and a vertical line.  The first user (you) are supposed to drag the right end of the horizontal line and the second user to drag the bottom end of the vertical line.  This works well in the splitting demo.  In the raising demo, however, the system has raised the constraints too far and has removed precious degrees of freedom from the objects.  Thus the constraints (you, the second user, horizontal, vertical) cannot all be solved simultaneously.
  2664. '!
  2665.  
  2666.  
  2667. !SplittingDemo methodsFor: 'initialize-release'!
  2668.  
  2669. create
  2670.     | hl vl m c |
  2671.     Transcript cr; show: 'Building the ' , self class name , '..'.
  2672.     Transcript cr; show: '..adding the components'.
  2673.     m _ FakeMouseGlyph new initialize.
  2674.     hl _ LineGlyph new.
  2675.     hl moveTo: 100 @ 100.
  2676.     vl _ LineGlyph new.
  2677.     vl moveTo: 100 @ 150.
  2678.     self addGlyph: m; addGlyph: hl; addGlyph: vl.
  2679.     Transcript cr; show: '..adding the consistency constraints'.
  2680.     EqualityConstraint
  2681.         var: hl p1 yVar
  2682.         var: hl p2 yVar
  2683.         strength: #required.
  2684.     EqualityConstraint
  2685.         var: vl p1 xVar
  2686.         var: vl p2 xVar
  2687.         strength: #required.
  2688.     EqualityConstraint
  2689.         var: hl p1 yVar
  2690.         var: vl p1 yVar
  2691.         strength: #required.
  2692.     EqualityConstraint
  2693.         var: hl p1 xVar
  2694.         var: vl p1 xVar
  2695.         strength: #required.
  2696.     EqualityConstraint
  2697.         var: vl p2 xVar
  2698.         var: m xVar
  2699.         strength: #required.
  2700.     EqualityConstraint
  2701.         var: vl p2 yVar
  2702.         var: m yVar
  2703.         strength: #required.
  2704.     "c _ Constraint names: #(new old ) methods: #('new _ ((old + SplittingDemo nextRandom) min: 350) max: 5' ).
  2705.     fakemouse _ Array with: (c copy
  2706.                     var: m xVar
  2707.                     var: m xVar last
  2708.                     strength: #default)
  2709.                 with: (c copy
  2710.                         var: m yVar
  2711.                         var: m yVar last
  2712.                         strength: #default)."
  2713.     fakemouse _ Array new: 2.
  2714.     fakemouse at: 1 put: ((Constraint
  2715.         names: #(new old )
  2716.         methods: #('new _ SplittingDemo nextRandomX' ))
  2717.             var: m xVar
  2718.             var: m xVar last
  2719.             strength: #default).
  2720.     fakemouse at: 2 put: ((Constraint
  2721.         names: #(new old )
  2722.         methods: #('new _ SplittingDemo nextRandomY' ))
  2723.             var: m yVar
  2724.             var: m yVar last
  2725.             strength: #default).
  2726.     Transcript cr; show: 'finished'!
  2727.  
  2728. initialize
  2729.     super initialize.
  2730.     self create! !
  2731.  
  2732. !SplittingDemo methodsFor: 'public'!
  2733.  
  2734. open
  2735.     "SplittingDemo new open"
  2736.  
  2737.     | topView |
  2738.     topView _ SpecialSystemView
  2739.                 model: nil
  2740.                 label: 'Splitting'
  2741.                 minimumSize: 400 @ 400.
  2742.     topView borderWidth: 1; addSubView: (SceneView new initialize model: self).
  2743.     topView controller open! !
  2744.  
  2745. !SplittingDemo methodsFor: 'testing'!
  2746.  
  2747. isAnimated
  2748.     ^true! !
  2749.  
  2750. !SplittingDemo methodsFor: 'background processing'!
  2751.  
  2752. computeBackgroundPlan
  2753.     ^Planner extractPlanFromInputConstraints: fakemouse!
  2754.  
  2755. initialAnimationConstraints
  2756.     ^fakemouse! !
  2757. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  2758.  
  2759. SplittingDemo class
  2760.     instanceVariableNames: ''!
  2761.  
  2762.  
  2763. !SplittingDemo class methodsFor: 'class initialization'!
  2764.  
  2765. initialize
  2766.     "SplittingDemo initialize"
  2767.  
  2768.     RandomStream _ Random new.
  2769.     RandomStream _ Array with: 1 with: 113@210 with: self pathArray!
  2770.  
  2771. pathArray
  2772.     | a |
  2773.     a _ OrderedCollection new.
  2774.     a add: 113 @ 211.
  2775.     a add: 113 @ 212.
  2776.     a add: 113 @ 217.
  2777.     a add: 113 @ 221.
  2778.     a add: 115 @ 225.
  2779.     a add: 115 @ 229.
  2780.     a add: 119 @ 233.
  2781.     a add: 123 @ 233.
  2782.     a add: 127 @ 237.
  2783.     a add: 131 @ 241.
  2784.     a add: 132 @ 241.
  2785.     a add: 133 @ 241.
  2786.     a add: 134 @ 241.
  2787.     a add: 135 @ 241.
  2788.     a add: 139 @ 242.
  2789.     a add: 143 @ 242.
  2790.     a add: 147 @ 242.
  2791.     a add: 151 @ 244.
  2792.     a add: 155 @ 244.
  2793.     a add: 159 @ 244.
  2794.     a add: 163 @ 244.
  2795.     a add: 167 @ 244.
  2796.     a add: 171 @ 244.
  2797.     a add: 175 @ 244.
  2798.     a add: 179 @ 245.
  2799.     a add: 183 @ 245.
  2800.     a add: 187 @ 247.
  2801.     a add: 191 @ 247.
  2802.     a add: 195 @ 249.
  2803.     a add: 197 @ 251.
  2804.     a add: 201 @ 255.
  2805.     a add: 203 @ 259.
  2806.     a add: 207 @ 261.
  2807.     a add: 209 @ 265.
  2808.     a add: 211 @ 269.
  2809.     a add: 213 @ 273.
  2810.     a add: 215 @ 277.
  2811.     a add: 216 @ 281.
  2812.     a add: 216 @ 285.
  2813.     a add: 218 @ 289.
  2814.     a add: 218 @ 293.
  2815.     a add: 218 @ 297.
  2816.     a add: 218 @ 301.
  2817.     a add: 218 @ 305.
  2818.     a add: 216 @ 309.
  2819.     a add: 216 @ 313.
  2820.     a add: 212 @ 317.
  2821.     a add: 212 @ 321.
  2822.     a add: 208 @ 325.
  2823.     a add: 204 @ 329.
  2824.     a add: 200 @ 333.
  2825.     a add: 198 @ 337.
  2826.     a add: 197 @ 338.
  2827.     a add: 196 @ 338.
  2828.     a add: 192 @ 340.
  2829.     a add: 191 @ 340.
  2830.     a add: 187 @ 340.
  2831.     a add: 183 @ 340.
  2832.     a add: 179 @ 340.
  2833.     a add: 175 @ 339.
  2834.     a add: 171 @ 339.
  2835.     a add: 167 @ 339.
  2836.     a add: 163 @ 337.
  2837.     a add: 159 @ 333.
  2838.     a add: 155 @ 331.
  2839.     a add: 151 @ 327.
  2840.     a add: 149 @ 323.
  2841.     a add: 147 @ 319.
  2842.     a add: 145 @ 315.
  2843.     a add: 145 @ 311.
  2844.     a add: 141 @ 307.
  2845.     a add: 139 @ 303.
  2846.     a add: 139 @ 299.
  2847.     a add: 137 @ 295.
  2848.     a add: 135 @ 291.
  2849.     a add: 133 @ 287.
  2850.     a add: 129 @ 283.
  2851.     a add: 125 @ 279.
  2852.     a add: 121 @ 275.
  2853.     a add: 117 @ 275.
  2854.     a add: 113 @ 271.
  2855.     a add: 112 @ 271.
  2856.     a add: 111 @ 271.
  2857.     a add: 107 @ 270.
  2858.     a add: 103 @ 270.
  2859.     a add: 99 @ 270.
  2860.     a add: 95 @ 268.
  2861.     a add: 91 @ 268.
  2862.     a add: 87 @ 268.
  2863.     a add: 83 @ 270.
  2864.     a add: 79 @ 270.
  2865.     a add: 75 @ 270.
  2866.     a add: 71 @ 270.
  2867.     a add: 67 @ 270.
  2868.     a add: 63 @ 270.
  2869.     a add: 59 @ 270.
  2870.     a add: 55 @ 270.
  2871.     a add: 51 @ 266.
  2872.     a add: 47 @ 266.
  2873.     a add: 43 @ 262.
  2874.     a add: 39 @ 260.
  2875.     a add: 35 @ 258.
  2876.     a add: 31 @ 254.
  2877.     a add: 29 @ 250.
  2878.     a add: 29 @ 246.
  2879.     a add: 27 @ 242.
  2880.     a add: 27 @ 238.
  2881.     a add: 27 @ 234.
  2882.     a add: 27 @ 230.
  2883.     a add: 27 @ 226.
  2884.     a add: 26 @ 222.
  2885.     a add: 26 @ 218.
  2886.     a add: 26 @ 214.
  2887.     a add: 26 @ 210.
  2888.     a add: 30 @ 206.
  2889.     a add: 30 @ 202.
  2890.     a add: 31 @ 198.
  2891.     a add: 33 @ 194.
  2892.     a add: 35 @ 190.
  2893.     a add: 37 @ 186.
  2894.     a add: 39 @ 182.
  2895.     a add: 41 @ 180.
  2896.     a add: 45 @ 176.
  2897.     a add: 49 @ 174.
  2898.     a add: 51 @ 172.
  2899.     a add: 55 @ 168.
  2900.     a add: 61 @ 165.
  2901.     a add: 65 @ 162.
  2902.     a add: 71 @ 159.
  2903.     a add: 77 @ 156.
  2904.     a add: 80 @ 150.
  2905.     a add: 86 @ 147.
  2906.     a add: 92 @ 145.
  2907.     a add: 96 @ 145.
  2908.     a add: 102 @ 143.
  2909.     a add: 106 @ 143.
  2910.     a add: 110 @ 143.
  2911.     a add: 116 @ 143.
  2912.     a add: 122 @ 143.
  2913.     a add: 128 @ 143.
  2914.     a add: 132 @ 145.
  2915.     a add: 136 @ 147.
  2916.     a add: 138 @ 151.
  2917.     a add: 142 @ 153.
  2918.     a add: 144 @ 155.
  2919.     a add: 146 @ 159.
  2920.     a add: 148 @ 161.
  2921.     a add: 152 @ 165.
  2922.     a add: 152 @ 169.
  2923.     a add: 156 @ 173.
  2924.     a add: 156 @ 177.
  2925.     a add: 156 @ 181.
  2926.     a add: 154 @ 185.
  2927.     a add: 154 @ 189.
  2928.     a add: 150 @ 193.
  2929.     a add: 148 @ 197.
  2930.     a add: 144 @ 201.
  2931.     a add: 144 @ 205.
  2932.     a add: 140 @ 207.
  2933.     a add: 139 @ 208.
  2934.     a add: 138 @ 208.
  2935.     a add: 137 @ 209.
  2936.     a add: 136 @ 209.
  2937.     a add: 135 @ 210.
  2938.     a add: 134 @ 210.
  2939.     a add: 133 @ 210.
  2940.     a add: 132 @ 211.
  2941.     a add: 131 @ 211.
  2942.     a add: 130 @ 211.
  2943.     a add: 129 @ 211.
  2944.     a add: 128 @ 212.
  2945.     a add: 127 @ 212.
  2946.     a add: 126 @ 212.
  2947.     a add: 125 @ 212.
  2948.     a add: 124 @ 212.
  2949.     a add: 124 @ 211.
  2950.     a add: 123 @ 211.
  2951.     a add: 122 @ 211.
  2952.     a add: 121 @ 210.
  2953.     a add: 120 @ 210.
  2954.     a add: 119 @ 210.
  2955.     a add: 118 @ 210.
  2956.     ^a asArray! !
  2957.  
  2958. !SplittingDemo class methodsFor: 'random numbers'!
  2959.  
  2960. nextRandom
  2961.     | v |
  2962.     v _ (RandomStream next * 20.0) truncated - 4.
  2963.     v > 4 ifTrue: [v _ 0].
  2964.     ^v!
  2965.  
  2966. nextRandomX
  2967.     | i |
  2968.     i _ RandomStream at: 1.
  2969.     i > (RandomStream at: 3) size ifTrue: [i _ RandomStream at: 1 put: 1].
  2970.     RandomStream at: 2 put: ((RandomStream at: 3) at: i).
  2971.     RandomStream at: 1 put: (i + 1).
  2972.     ^(RandomStream at: 2) x!
  2973.  
  2974. nextRandomY
  2975.     ^(RandomStream at: 2) y! !
  2976.  
  2977. !SplittingDemo class methodsFor: 'access'!
  2978.  
  2979. infoSize
  2980.     ^700@280! !
  2981.  
  2982. SplittingDemo initialize!
  2983.  
  2984.  
  2985. ScriptGlyph subclass: #TwoProngTextGlyph
  2986.     instanceVariableNames: 'textGlyph left right offset '
  2987.     classVariableNames: 'CenterOffsetConstraint '
  2988.     poolDictionaries: ''
  2989.     category: 'Minstrel-SIGGRAPH'!
  2990.  
  2991.  
  2992. !TwoProngTextGlyph methodsFor: 'initialize-release'!
  2993.  
  2994. initialize
  2995.     "TwoProngTextGlyph releaseConstraints"
  2996.  
  2997.     super initialize.
  2998.     textGlyph _ TextGlyph new initialize.
  2999.     left _ PointGlyph new initialize.
  3000.     right _ PointGlyph new initialize.
  3001.     left moveTo: 10 @ 10.
  3002.     right moveTo: 100 @ 10.
  3003.     textGlyph moveTo: 40 @ 15.
  3004.     offset _ PointGlyph new initialize.
  3005.     offset moveTo: 10 @ 40.
  3006.     CenterOffsetConstraint isNil ifTrue: [CenterOffsetConstraint _ (Constraint names: #(out left right off ) methods: #('out _ ((left + right) // 2) - off' 'off _ ((left + right) // 2) - out' ))
  3007.                     name: 'center offset'].
  3008.     StayConstraint
  3009.         var: offset xVar
  3010.         strength: #default.
  3011.     CenterOffsetConstraint copy
  3012.         var: textGlyph box leftVar
  3013.         var: left xVar
  3014.         var: right xVar
  3015.         var: offset xVar
  3016.         strength: #required.
  3017.     StayConstraint
  3018.         var: offset yVar
  3019.         strength: #default.
  3020.     CenterOffsetConstraint copy
  3021.         var: textGlyph box topVar
  3022.         var: left yVar
  3023.         var: right yVar
  3024.         var: offset yVar
  3025.         strength: #required!
  3026.  
  3027. left: l right: r string: s
  3028.     | stays |  
  3029.     stays _ Set new.
  3030.     stays add: (StayConstraint
  3031.         var: textGlyph box leftVar
  3032.         strength: #strongPreferred).
  3033.     stays add: (StayConstraint
  3034.         var: textGlyph box topVar
  3035.         strength: #strongPreferred).
  3036.     EqualityConstraint
  3037.         var: l xVar
  3038.         var: left xVar
  3039.         strength: #required.
  3040.     EqualityConstraint
  3041.         var: l yVar
  3042.         var: left yVar
  3043.         strength: #required.
  3044.     EqualityConstraint
  3045.         var: r xVar
  3046.         var: right xVar
  3047.         strength: #required.
  3048.     EqualityConstraint
  3049.         var: r yVar
  3050.         var: right yVar
  3051.         strength: #required.
  3052.     stays do: [:each | each destroyConstraint].
  3053.     textGlyph text: s! !
  3054.  
  3055. !TwoProngTextGlyph methodsFor: 'accessing'!
  3056.  
  3057. left ^left!
  3058.  
  3059. right ^right!
  3060.  
  3061. text
  3062.     ^textGlyph! !
  3063.  
  3064. !TwoProngTextGlyph methodsFor: 'glyph protocol'!
  3065.  
  3066. boundingBox
  3067.     ^textGlyph boundingBox!
  3068.  
  3069. displayOn: aDisplayMedium at: aDisplayPoint clip: clipBox 
  3070.     | r |
  3071.     r _ textGlyph box asRectangle moveBy: aDisplayPoint.
  3072.     (Line
  3073.         from: left asPoint
  3074.         to: r left @ r center y
  3075.         withForm: (Form extent: 1 @ 1) black)
  3076.         displayOn: aDisplayMedium
  3077.         at: aDisplayPoint.
  3078.     (Line
  3079.         from: right asPoint
  3080.         to: r right @ r center y
  3081.         withForm: (Form extent: 1 @ 1) black)
  3082.         displayOn: aDisplayMedium
  3083.         at: aDisplayPoint.
  3084.     aDisplayMedium fill: (r insetBy: -1 @ -1) mask: Form white.
  3085.     textGlyph
  3086.         displayOn: aDisplayMedium
  3087.         at: aDisplayPoint
  3088.         clip: clipBox.
  3089.     aDisplayMedium border: (r insetBy: -3 @ -3)
  3090.         width: 2.
  3091.     false ifTrue: [self stilltodo]!
  3092.  
  3093. isSelectable
  3094.     ^true!
  3095.  
  3096. locationPoints
  3097.     ^Array
  3098.         with: textGlyph box center"
  3099.         with: left asPoint
  3100.         with: right asPoint"! !
  3101.  
  3102. !TwoProngTextGlyph methodsFor: 'enumeration'!
  3103.  
  3104. selectableGlyphsDo: aBlock 
  3105.     aBlock value: self.
  3106.     aBlock value: textGlyph.
  3107. aBlock value: left.
  3108. aBlock value: right!
  3109.  
  3110. visibleGlyphsDo: aBlock 
  3111.     aBlock value: self.
  3112.     aBlock value: textGlyph! !
  3113. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  3114.  
  3115. TwoProngTextGlyph class
  3116.     instanceVariableNames: ''!
  3117.  
  3118.  
  3119. !TwoProngTextGlyph class methodsFor: 'classification'!
  3120.  
  3121. glyphCategory
  3122.     ^'SIGGRAPH'! !
  3123.  
  3124. !TwoProngTextGlyph class methodsFor: 'constraint release'!
  3125.  
  3126. releaseConstraints
  3127.     "TwoProngTextGlyph releaseConstraints"
  3128.  
  3129.     CenterOffsetConstraint _ nil! !
  3130.  
  3131.  
  3132. !UnaryConstraint methodsFor: 'initialize-release'!
  3133.  
  3134. var: aVariable primstrength: s
  3135.     strength _ s.
  3136.     output _ aVariable.
  3137.     satisfied _ false.
  3138.     self addConstraint.! !
  3139.  
  3140. TextGlyph subclass: #BoxTextGlyph
  3141.     instanceVariableNames: ''
  3142.     classVariableNames: ''
  3143.     poolDictionaries: ''
  3144.     category: 'Minstrel-SIGGRAPH'!
  3145.  
  3146.  
  3147. !BoxTextGlyph methodsFor: 'glyph protocol'!
  3148.  
  3149. boundingBox
  3150.     "Answer my bounding box."
  3151.  
  3152.     ^((box left - 4)@(box top - 4)) corner:
  3153.         ((box right + 4)@(box bottom + 4))!
  3154.  
  3155. displayOn: aDisplayMedium at: aDisplayPoint clip: clipBox
  3156.     | scanner  r |
  3157.     r _ box asRectangle moveBy: aDisplayPoint.
  3158.     scanner _ QuickPrint
  3159.         newOn: aDisplayMedium
  3160.         box: ((r topLeft) corner: clipBox bottomRight)
  3161.         font: font value.
  3162.     aDisplayMedium fill: (r insetBy: -1 @ -1) mask: Form white.
  3163.     aDisplayMedium border: (r insetBy: -3 @ -3)
  3164.         width: 2.
  3165.     scanner drawString: text value.! !
  3166. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  3167.  
  3168. BoxTextGlyph class
  3169.     instanceVariableNames: ''!
  3170.  
  3171.  
  3172. !BoxTextGlyph class methodsFor: 'classification'!
  3173.  
  3174. glyphCategory
  3175.     ^'SIGGRAPH'! !
  3176.  
  3177. Plus1Demo subclass: #Plus2Demo
  3178.     instanceVariableNames: ''
  3179.     classVariableNames: ''
  3180.     poolDictionaries: ''
  3181.     category: 'Minstrel-SIGGRAPH'!
  3182.  
  3183.  
  3184. !Plus2Demo methodsFor: 'initialize-release'!
  3185.  
  3186. createDefaults
  3187.     | ss |
  3188.     ss _ #(3 3 4 4 5 5 6 ).
  3189.     values with: ss do: [:each :s | StayConstraint new var: each primstrength: (Strength new initializeWith: 'special' , s printString and: s)]! !
  3190.  
  3191. !Plus2Demo methodsFor: 'public'!
  3192.  
  3193. open
  3194.     "Plus2Demo new open"
  3195.  
  3196.     | topView |
  3197.     topView _ SpecialSystemView
  3198.                 model: nil
  3199.                 label: 'Plus Demo With Hierarchy'
  3200.                 minimumSize: 400 @ 300.
  3201.     topView borderWidth: 1; addSubView: (SceneView new initialize model: self).
  3202.     topView controller open! !
  3203.  
  3204. PointGlyph subclass: #SIGGRAPHAnchorGlyph
  3205.     instanceVariableNames: ''
  3206.     classVariableNames: 'AnchorForm '
  3207.     poolDictionaries: ''
  3208.     category: 'Minstrel-SIGGRAPH'!
  3209.  
  3210.  
  3211. !SIGGRAPHAnchorGlyph methodsFor: 'glyph protocol'!
  3212.  
  3213. boundingBox
  3214.  
  3215.     ^(self rounded - (4@3)) extent: 6@6!
  3216.  
  3217. displayOn: aDisplayMedium at: aDisplayPoint clip: clipBox 
  3218.     AnchorForm
  3219.         displayOn: aDisplayMedium
  3220.         at: aDisplayPoint + self asPoint
  3221.         clippingBox: clipBox
  3222.         rule: Form paint
  3223.         mask: Form black! !
  3224.  
  3225. !SIGGRAPHAnchorGlyph methodsFor: 'merging'!
  3226.  
  3227. canMergeWith: aGlyph 
  3228.     ^false!
  3229.  
  3230. changing
  3231.     "This is a hack to prevent the ugly black can-merge box from showing up around 
  3232.     my anchor."
  3233.  
  3234.     ^true! !
  3235. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  3236.  
  3237. SIGGRAPHAnchorGlyph class
  3238.     instanceVariableNames: ''!
  3239.  
  3240.  
  3241. !SIGGRAPHAnchorGlyph class methodsFor: 'class initialization'!
  3242.  
  3243. initialize
  3244.     "SIGGRAPHAnchorGlyph initialize."
  3245.  
  3246.     AnchorForm _ Form
  3247.             extent: 18 @ 19
  3248.             fromArray: #(480 0 1008 0 1008 0 480 0 192 0 192 0 192 0 192 0 192 0 8385 0 28867 32768 63687 49152 24769 32768 24769 32768 28867 32768 14535 0 7902 0 4092 0 1008 0 )
  3249.             offset: -10 @ -2.! !
  3250.  
  3251. !SIGGRAPHAnchorGlyph class methodsFor: 'classification'!
  3252.  
  3253. glyphCategory
  3254.     ^'SIGGRAPH'! !
  3255.  
  3256. SIGGRAPHAnchorGlyph initialize!
  3257.  
  3258.  
  3259. Scene subclass: #ThreePlanetDemo
  3260.     instanceVariableNames: 'theta1 r1 theta2 r2 '
  3261.     classVariableNames: ''
  3262.     poolDictionaries: ''
  3263.     category: 'Minstrel-SIGGRAPH'!
  3264. ThreePlanetDemo comment:
  3265. '                            ***** Animation (Orbiting Planetoids) *****
  3266.  
  3267. Constraints are especially useful for two aspects of graphics: static layout and dynamic behavior.  Constraints can be used to declaratively specify the layout of various graphical objects to ensure that positioning and other relations are maintained.  Perhaps more interesting, though, is the use of constraints to define dynamic behavior, e.g., animations.  Constraints are a natural mechanism for describing physical laws (even imaginary "Wiley E. Coyote" ones).  
  3268.  
  3269. These two demos illustrate the use of simple animation constraints.  In the fake-gravity demo, the slides control the orbit radius of the two planets and simple computation is used to find the next position of each planet.  Interestingly enough, the animation can continue while the user is interacting with the system---after all, the user''s interaction is implemented by constraints and the animation is implemented by constraints, thus the system can automatically solve the two sets together.  Thus the user can move the slider while the planets orbit.  However, the user can also grab any planet and drag it around and the other planets will continue their orbits, although now centered on the user''s planet.  This "re-centering" is because the user''s interaction constraint is stronger than the rest.
  3270.  
  3271. In the real-gravity demo, the slider control gravity and the four vectors illustrate the acceleration and velocity of the two planets.  All of the constraints are multi-directional, thus if the planets are dragged around, the vectors will indicate the velocity and acceleration of the mouse!!  And, if the velocity vector is dragged around, the acceleration and planet motion will match, and so on.  Unfortunately, it is very difficult to get the planets to orbit (or to do anything at all) which is why the fake-gravity demo is also supplied.
  3272. '!
  3273.  
  3274.  
  3275. !ThreePlanetDemo methodsFor: 'initialize-release'!
  3276.  
  3277. create
  3278.     | p1 p2 p3 h1 h2 c2 c3 |
  3279.     Transcript cr; show: 'Building the ', self class name, '..'.
  3280.     theta1 _ FreeVariable value: 0.0.
  3281.     r1 _ FreeVariable value: 100.0.
  3282.     theta2 _ FreeVariable value: 0.0.
  3283.     r2 _ FreeVariable value: 40.0.
  3284.     Transcript cr; show: '..adding planets'.
  3285.     p1 _ PlanetGlyph new initialize.
  3286.     p1 form1.
  3287.     p1 moveTo: 250 @ 210.
  3288.     p2 _ PlanetGlyph new initialize.
  3289.     p2 form2.
  3290.     p2 moveTo: 150 @ 210.
  3291.     p3 _ PlanetGlyph new initialize.
  3292.     p3 form3.
  3293.     p3 moveTo: 110 @ 210.
  3294.     self addGlyph: p1; addGlyph: p2; addGlyph: p3.
  3295.     Transcript cr; show: '..adding control sliders'.
  3296.     h1 _ (HSliderGlyph on: r1) minVal: 0.1; maxVal: 200.0; value: 100.0; moveTo: 150 @ 400.
  3297.     h2 _ (HSliderGlyph on: r2) minVal: 0.1; maxVal: 200.0; value: 40.0; moveTo: 360 @ 400.
  3298.     self addGlyph: h1; addGlyph: h2.
  3299.     Transcript cr; show: '..adding interface constraints'.
  3300.     StayConstraint var: p1 xVar strength: #default.
  3301.     StayConstraint var: p1 yVar strength: #default.
  3302.     c2 _ Constraint
  3303.             names: #(theta r xp xs )
  3304.             methods: #('xp _ xs + (r * theta cos)' 'xs _ xp - (r * theta cos)' ).
  3305.     c3 _ Constraint
  3306.             names: #(theta r yp ys )
  3307.             methods: #('yp _ ys + (r * theta sin)' 'ys _ yp - (r * theta sin)' ).
  3308.     (Constraint
  3309.             names: #(theta pretheta r )
  3310.             methods: #('theta _ pretheta + (5.0/r)' ))
  3311.         var: theta1 var: theta1 last var: r1 strength: #required.
  3312.     c2 copy var: theta1 var: r1 var: p1 xVar var: p2 xVar strength: #required.
  3313.     c3 copy var: theta1 var: r1 var: p1 yVar var: p2 yVar strength: #required.
  3314.     (Constraint
  3315.             names: #(theta pretheta r )
  3316.             methods: #('theta _ pretheta + (10.0/r)' ))
  3317.         var: theta2 var: theta2 last var: r2 strength: #required.
  3318.     c2 copy var: theta2 var: r2 var: p2 xVar var: p3 xVar strength: #required.
  3319.     c3 copy var: theta2 var: r2 var: p2 yVar var: p3 yVar strength: #required.
  3320.     Transcript cr; show: 'finished'!
  3321.  
  3322. initialize
  3323.     super initialize.
  3324.     self create! !
  3325.  
  3326. !ThreePlanetDemo methodsFor: 'public'!
  3327.  
  3328. open
  3329.     "ThreePlanetDemo new open"
  3330.  
  3331.     | topView |
  3332.     topView _ SpecialSystemView
  3333.                 model: nil
  3334.                 label: 'Planet Demo (Fake Gravity)'
  3335.                 minimumSize: 525 @ 425.
  3336.     topView borderWidth: 1; addSubView: (SceneView new initialize model: self).
  3337.     topView controller open! !
  3338.  
  3339. !ThreePlanetDemo methodsFor: 'testing'!
  3340.  
  3341. isAnimated
  3342.     ^true! !
  3343.  
  3344. !ThreePlanetDemo methodsFor: 'background processing'!
  3345.  
  3346. computeBackgroundPlan
  3347.     ^Planner extractPlanFromVariables: (Array with: theta1 with: theta2)! !
  3348. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  3349.  
  3350. ThreePlanetDemo class
  3351.     instanceVariableNames: ''!
  3352.  
  3353.  
  3354. !ThreePlanetDemo class methodsFor: 'access'!
  3355.  
  3356. infoSize
  3357.     ^600@360! !
  3358.  
  3359.  
  3360. !Strength methodsFor: 'private'!
  3361.  
  3362. initializeWith: symVal and: numVal
  3363.     symbolicValue _ symVal.
  3364.     arithmeticValue _ numVal! !
  3365.  
  3366. Scene subclass: #AnchorLine2Demo
  3367.     instanceVariableNames: ''
  3368.     classVariableNames: ''
  3369.     poolDictionaries: ''
  3370.     category: 'Minstrel-SIGGRAPH'!
  3371.  
  3372.  
  3373. !AnchorLine2Demo methodsFor: 'initialize-release'!
  3374.  
  3375. create
  3376.     | l f |
  3377.     Transcript cr; show: 'Building the ' , self class name , '..'.
  3378.     Transcript cr; show: '..adding the components'.
  3379.     f _ SIGGRAPHAnchorGlyph new initialize.
  3380.     l _ LineGlyph new.
  3381.     l moveTo: 100 @ 100.
  3382.     self addGlyph: f; addGlyph: l.
  3383.     Transcript cr; show: '..adding the consistency constraints'.
  3384.     EqualityConstraint
  3385.         var: l p1 yVar
  3386.         var: l p2 yVar
  3387.         strength: #required.
  3388.     EqualityConstraint
  3389.         var: l p1 xVar
  3390.         var: f xVar
  3391.         strength: #required.
  3392.     EqualityConstraint
  3393.         var: l p1 yVar
  3394.         var: f yVar
  3395.         strength: #required.
  3396.     StayConstraint var: f xVar strength: #strongPreferred.
  3397.     StayConstraint var: f yVar strength: #strongPreferred.
  3398.     Transcript cr; show: 'finished'!
  3399.  
  3400. initialize
  3401.     super initialize.
  3402.     self create! !
  3403.  
  3404. !AnchorLine2Demo methodsFor: 'public'!
  3405.  
  3406. open
  3407.     "AnchorLine2Demo new open"
  3408.  
  3409.     | topView |
  3410.     topView _ SpecialSystemView
  3411.                 model: nil
  3412.                 label: 'Horizontal Line, Anchor'
  3413.                 minimumSize: 300 @ 200.
  3414.     topView borderWidth: 1; addSubView: (SceneView new initialize model: self).
  3415.     topView controller open! !
  3416.  
  3417. SceneController subclass: #MacDrawDemoController
  3418.     instanceVariableNames: ''
  3419.     classVariableNames: ''
  3420.     poolDictionaries: ''
  3421.     category: 'Minstrel-SIGGRAPH'!
  3422.  
  3423.